mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-01 01:23:26 +00:00
Remove WithOptconstParam.
This commit is contained in:
parent
0e017fc94a
commit
b275d2c30b
@ -6,7 +6,7 @@ use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::vec::IndexSlice;
|
||||
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
|
||||
use rustc_middle::mir::Body;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub use super::{
|
||||
facts::{AllFacts as PoloniusInput, RustcFacts},
|
||||
@ -28,12 +28,9 @@ pub use super::{
|
||||
/// that shows how to do this at `tests/run-make/obtain-borrowck/`.
|
||||
///
|
||||
/// * Polonius is highly unstable, so expect regular changes in its signature or other details.
|
||||
pub fn get_body_with_borrowck_facts(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> BodyWithBorrowckFacts<'_> {
|
||||
pub fn get_body_with_borrowck_facts(tcx: TyCtxt<'_>, def: LocalDefId) -> BodyWithBorrowckFacts<'_> {
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build();
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build();
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()
|
||||
|
@ -19,7 +19,7 @@ use rustc_middle::mir::{
|
||||
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
|
||||
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
|
||||
};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty, TypeckResults};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
|
||||
use rustc_middle::util::CallKind;
|
||||
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
@ -1350,8 +1350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
finder.visit_expr(body_expr);
|
||||
let Some((closure_expr, closure)) = finder.res else { return };
|
||||
|
||||
let typeck_results: &TypeckResults<'_> =
|
||||
tcx.typeck_opt_const_arg(self.body.source.with_opt_param().as_local().unwrap());
|
||||
let typeck_results = tcx.typeck(self.mir_def_id());
|
||||
|
||||
// Check that the parent of the closure is a method call,
|
||||
// with receiver matching with local's type (modulo refs)
|
||||
|
@ -119,24 +119,12 @@ impl<'tcx> TyCtxtConsts<'tcx> {
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
mir_borrowck: |tcx, did| {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
|
||||
tcx.mir_borrowck_const_arg(def)
|
||||
} else {
|
||||
mir_borrowck(tcx, ty::WithOptConstParam::unknown(did))
|
||||
}
|
||||
},
|
||||
mir_borrowck_const_arg: |tcx, (did, param_did)| {
|
||||
mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
},
|
||||
..*providers
|
||||
};
|
||||
*providers = Providers { mir_borrowck, ..*providers };
|
||||
}
|
||||
|
||||
fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &BorrowCheckResult<'_> {
|
||||
fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.to_def_id()));
|
||||
|
||||
if input_body.borrow().should_skip() {
|
||||
debug!("Skipping borrowck because of injected body");
|
||||
@ -150,7 +138,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor
|
||||
return tcx.arena.alloc(result);
|
||||
}
|
||||
|
||||
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
|
||||
let hir_owner = tcx.hir().local_def_id_to_hir_id(def).owner;
|
||||
|
||||
let infcx =
|
||||
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
|
||||
@ -167,19 +155,19 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor
|
||||
/// If `return_body_with_facts` is true, then return the body with non-erased
|
||||
/// region ids on which the borrow checking was performed together with Polonius
|
||||
/// facts.
|
||||
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")]
|
||||
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
|
||||
fn do_mir_borrowck<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
input_body: &Body<'tcx>,
|
||||
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
||||
return_body_with_facts: bool,
|
||||
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
|
||||
let def = input_body.source.with_opt_param().as_local().unwrap();
|
||||
let def = input_body.source.def_id().expect_local();
|
||||
debug!(?def);
|
||||
|
||||
let tcx = infcx.tcx;
|
||||
let infcx = BorrowckInferCtxt::new(infcx);
|
||||
let param_env = tcx.param_env(def.did);
|
||||
let param_env = tcx.param_env(def);
|
||||
|
||||
let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
|
||||
for var_debug_info in &input_body.var_debug_info {
|
||||
@ -207,7 +195,7 @@ fn do_mir_borrowck<'tcx>(
|
||||
errors.set_tainted_by_errors(e);
|
||||
}
|
||||
let upvars: Vec<_> = tcx
|
||||
.closure_captures(def.did)
|
||||
.closure_captures(def)
|
||||
.iter()
|
||||
.map(|&captured_place| {
|
||||
let capture = captured_place.info.capture_kind;
|
||||
@ -249,7 +237,7 @@ fn do_mir_borrowck<'tcx>(
|
||||
.iterate_to_fixpoint()
|
||||
.into_results_cursor(&body);
|
||||
|
||||
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def.did).is_fn_or_closure();
|
||||
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
|
||||
let borrow_set =
|
||||
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data));
|
||||
|
||||
|
@ -61,7 +61,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
|
||||
body: &mut Body<'tcx>,
|
||||
promoted: &mut IndexSlice<Promoted, Body<'tcx>>,
|
||||
) -> UniversalRegions<'tcx> {
|
||||
let def = body.source.with_opt_param().as_local().unwrap();
|
||||
let def = body.source.def_id().expect_local();
|
||||
|
||||
debug!(?def);
|
||||
|
||||
|
@ -394,7 +394,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
self.cx.ascribe_user_type(
|
||||
constant.literal.ty(),
|
||||
UserType::TypeOf(
|
||||
uv.def.did,
|
||||
uv.def,
|
||||
UserSubsts { substs: uv.substs, user_self_ty: None },
|
||||
),
|
||||
locations.span(&self.cx.body),
|
||||
@ -1766,7 +1766,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
if let Some(uv) = maybe_uneval {
|
||||
if uv.promoted.is_none() {
|
||||
let tcx = self.tcx();
|
||||
let def_id = uv.def.def_id_for_type_of();
|
||||
let def_id = uv.def;
|
||||
if tcx.def_kind(def_id) == DefKind::InlineConst {
|
||||
let def_id = def_id.expect_local();
|
||||
let predicates =
|
||||
|
@ -226,7 +226,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
/// known between those regions.
|
||||
pub fn new(
|
||||
infcx: &BorrowckInferCtxt<'_, 'tcx>,
|
||||
mir_def: ty::WithOptConstParam<LocalDefId>,
|
||||
mir_def: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Self {
|
||||
UniversalRegionsBuilder { infcx, mir_def, param_env }.build()
|
||||
@ -388,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
|
||||
struct UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
|
||||
mir_def: ty::WithOptConstParam<LocalDefId>,
|
||||
mir_def: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
@ -417,12 +417,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let mut indices = self.compute_indices(fr_static, defining_ty);
|
||||
debug!("build: indices={:?}", indices);
|
||||
|
||||
let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
|
||||
let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
||||
|
||||
// If this is a 'root' body (not a closure/generator/inline const), then
|
||||
// there are no extern regions, so the local regions start at the same
|
||||
// position as the (empty) sub-list of extern regions
|
||||
let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id {
|
||||
let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id {
|
||||
first_extern_index
|
||||
} else {
|
||||
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
|
||||
@ -433,7 +433,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
// }
|
||||
for_each_late_bound_region_in_recursive_scope(
|
||||
self.infcx.tcx,
|
||||
self.infcx.tcx.local_parent(self.mir_def.did),
|
||||
self.infcx.tcx.local_parent(self.mir_def),
|
||||
|r| {
|
||||
debug!(?r);
|
||||
if !indices.indices.contains_key(&r) {
|
||||
@ -462,13 +462,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
|
||||
let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
|
||||
FR,
|
||||
self.mir_def.did,
|
||||
self.mir_def,
|
||||
bound_inputs_and_output,
|
||||
&mut indices,
|
||||
);
|
||||
// Converse of above, if this is a function/closure then the late-bound regions declared on its
|
||||
// signature are local.
|
||||
for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
|
||||
for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| {
|
||||
debug!(?r);
|
||||
if !indices.indices.contains_key(&r) {
|
||||
let region_vid = {
|
||||
@ -492,7 +492,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
|
||||
let va_list_did = self.infcx.tcx.require_lang_item(
|
||||
LangItem::VaList,
|
||||
Some(self.infcx.tcx.def_span(self.mir_def.did)),
|
||||
Some(self.infcx.tcx.def_span(self.mir_def)),
|
||||
);
|
||||
|
||||
let reg_vid = self
|
||||
@ -544,11 +544,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
/// see `DefiningTy` for details.
|
||||
fn defining_ty(&self) -> DefiningTy<'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
||||
|
||||
match tcx.hir().body_owner_kind(self.mir_def.did) {
|
||||
match tcx.hir().body_owner_kind(self.mir_def) {
|
||||
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
|
||||
let defining_ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
|
||||
let defining_ty = tcx.type_of(self.mir_def).subst_identity();
|
||||
|
||||
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
|
||||
|
||||
@ -562,9 +562,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
}
|
||||
ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
|
||||
_ => span_bug!(
|
||||
tcx.def_span(self.mir_def.did),
|
||||
tcx.def_span(self.mir_def),
|
||||
"expected defining type for `{:?}`: `{:?}`",
|
||||
self.mir_def.did,
|
||||
self.mir_def,
|
||||
defining_ty
|
||||
),
|
||||
}
|
||||
@ -572,10 +572,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
|
||||
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||
if self.mir_def.did.to_def_id() == typeck_root_def_id {
|
||||
if self.mir_def.to_def_id() == typeck_root_def_id {
|
||||
let substs =
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
|
||||
DefiningTy::Const(self.mir_def.did.to_def_id(), substs)
|
||||
DefiningTy::Const(self.mir_def.to_def_id(), substs)
|
||||
} else {
|
||||
// FIXME this line creates a dependency between borrowck and typeck.
|
||||
//
|
||||
@ -587,15 +587,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
// below), so that `type_of(inline_const_def_id).substs(substs)` uses the
|
||||
// proper type with NLL infer vars.
|
||||
let ty = tcx
|
||||
.typeck(self.mir_def.did)
|
||||
.node_type(tcx.local_def_id_to_hir_id(self.mir_def.did));
|
||||
.typeck(self.mir_def)
|
||||
.node_type(tcx.local_def_id_to_hir_id(self.mir_def));
|
||||
let substs = InlineConstSubsts::new(
|
||||
tcx,
|
||||
InlineConstSubstsParts { parent_substs: identity_substs, ty },
|
||||
)
|
||||
.substs;
|
||||
let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs);
|
||||
DefiningTy::InlineConst(self.mir_def.did.to_def_id(), substs)
|
||||
DefiningTy::InlineConst(self.mir_def.to_def_id(), substs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -611,7 +611,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
defining_ty: DefiningTy<'tcx>,
|
||||
) -> UniversalRegionIndices<'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||
let fr_substs = match defining_ty {
|
||||
DefiningTy::Closure(_, substs)
|
||||
@ -647,7 +647,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
match defining_ty {
|
||||
DefiningTy::Closure(def_id, substs) => {
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let closure_sig = substs.as_closure().sig();
|
||||
let inputs_and_output = closure_sig.inputs_and_output();
|
||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
||||
@ -682,7 +682,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
DefiningTy::Generator(def_id, substs, movability) => {
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let resume_ty = substs.as_generator().resume_ty();
|
||||
let output = substs.as_generator().return_ty();
|
||||
let generator_ty = tcx.mk_generator(def_id, substs, movability);
|
||||
@ -700,14 +700,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
DefiningTy::Const(def_id, _) => {
|
||||
// For a constant body, there are no inputs, and one
|
||||
// "output" (the type of the constant).
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let ty = tcx.type_of(self.mir_def).subst_identity();
|
||||
let ty = indices.fold_to_region_vids(tcx, ty);
|
||||
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
||||
}
|
||||
|
||||
DefiningTy::InlineConst(def_id, substs) => {
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
assert_eq!(self.mir_def.to_def_id(), def_id);
|
||||
let ty = substs.as_inline_const().ty();
|
||||
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
|
||||
),
|
||||
},
|
||||
ConstantKind::Unevaluated(mir::UnevaluatedConst { def, .. }, _)
|
||||
if fx.tcx.is_static(def.did) =>
|
||||
if fx.tcx.is_static(def) =>
|
||||
{
|
||||
span_bug!(constant.span, "MIR constant refers to static");
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ fn exported_symbols_provider_local(
|
||||
match *mono_item {
|
||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
|
||||
if substs.non_erasable_generics().next().is_some() {
|
||||
let symbol = ExportedSymbol::Generic(def.did, substs);
|
||||
let symbol = ExportedSymbol::Generic(def, substs);
|
||||
symbols.push((
|
||||
symbol,
|
||||
SymbolExportInfo {
|
||||
|
@ -296,12 +296,12 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||
}
|
||||
|
||||
let cid = key.value;
|
||||
let def = cid.instance.def.with_opt_param();
|
||||
let is_static = tcx.is_static(def.did);
|
||||
let def = cid.instance.def.def_id();
|
||||
let is_static = tcx.is_static(def);
|
||||
|
||||
let mut ecx = InterpCx::new(
|
||||
tcx,
|
||||
tcx.def_span(def.did),
|
||||
tcx.def_span(def),
|
||||
key.param_env,
|
||||
// Statics (and promoteds inside statics) may access other statics, because unlike consts
|
||||
// they do not have to behave "as if" they were evaluated at runtime.
|
||||
|
@ -375,9 +375,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
|
||||
match instance {
|
||||
ty::InstanceDef::Item(def) => {
|
||||
if ecx.tcx.is_ctfe_mir_available(def.did) {
|
||||
Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def))
|
||||
} else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst {
|
||||
if ecx.tcx.is_ctfe_mir_available(def) {
|
||||
Ok(ecx.tcx.mir_for_ctfe(def))
|
||||
} else if ecx.tcx.def_kind(def) == DefKind::AssocConst {
|
||||
let guar = ecx.tcx.sess.delay_span_bug(
|
||||
rustc_span::DUMMY_SP,
|
||||
"This is likely a const item that is missing from its impl",
|
||||
@ -386,7 +386,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
} else {
|
||||
// `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
|
||||
// so this should be unreachable.
|
||||
let path = ecx.tcx.def_path_str(def.did);
|
||||
let path = ecx.tcx.def_path_str(def);
|
||||
bug!("trying to call extern function `{path}` at compile-time");
|
||||
}
|
||||
}
|
||||
@ -410,9 +410,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
// Execution might have wandered off into other crates, so we cannot do a stability-
|
||||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// at all.
|
||||
if !ecx.tcx.is_const_fn_raw(def.did) {
|
||||
if !ecx.tcx.is_const_fn_raw(def) {
|
||||
// allow calling functions inside a trait marked with #[const_trait].
|
||||
if !ecx.tcx.is_const_default_method(def.did) {
|
||||
if !ecx.tcx.is_const_default_method(def) {
|
||||
// We certainly do *not* want to actually call the fn
|
||||
// though, so be sure we return here.
|
||||
throw_unsup_format!("calling non-const function `{}`", instance)
|
||||
|
@ -461,10 +461,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
instance: ty::InstanceDef<'tcx>,
|
||||
promoted: Option<mir::Promoted>,
|
||||
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
|
||||
let def = instance.with_opt_param();
|
||||
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
|
||||
let body = if let Some(promoted) = promoted {
|
||||
&self.tcx.promoted_mir_opt_const_arg(def)[promoted]
|
||||
let def = instance.def_id();
|
||||
&self.tcx.promoted_mir(def)[promoted]
|
||||
} else {
|
||||
M::load_mir(self, instance)?
|
||||
};
|
||||
@ -502,13 +502,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).
|
||||
pub(super) fn resolve(
|
||||
&self,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
def: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
|
||||
trace!("resolve: {:?}, {:#?}", def, substs);
|
||||
trace!("param_env: {:#?}", self.param_env);
|
||||
trace!("substs: {:#?}", substs);
|
||||
match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env, def, substs) {
|
||||
match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) {
|
||||
Ok(Some(instance)) => Ok(instance),
|
||||
Ok(None) => throw_inval!(TooGeneric),
|
||||
|
||||
|
@ -83,8 +83,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
|
||||
}
|
||||
ty::FnDef(def_id, substs) => {
|
||||
let instance =
|
||||
self.resolve(ty::WithOptConstParam::unknown(def_id), substs)?;
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
(
|
||||
FnVal::Instance(instance),
|
||||
self.fn_abi_of_instance(instance, extra_args)?,
|
||||
|
@ -36,7 +36,7 @@ where
|
||||
ty::Closure(def_id, substs)
|
||||
| ty::Generator(def_id, substs, ..)
|
||||
| ty::FnDef(def_id, substs) => {
|
||||
let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id));
|
||||
let instance = ty::InstanceDef::Item(def_id);
|
||||
let unused_params = self.tcx.unused_generic_params(instance);
|
||||
for (index, subst) in substs.into_iter().enumerate() {
|
||||
let index = index
|
||||
|
@ -874,7 +874,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
debug!("Resolving ({:?}) -> {:?}", callee, instance);
|
||||
if let Ok(Some(func)) = instance {
|
||||
if let InstanceDef::Item(def) = func.def {
|
||||
callee = def.did;
|
||||
callee = def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,9 +364,8 @@ where
|
||||
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
|
||||
|
||||
// Don't peek inside trait associated constants.
|
||||
if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
|
||||
assert_eq!(def.const_param_did, None, "expected associated const: {def:?}");
|
||||
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did);
|
||||
if promoted.is_none() && cx.tcx.trait_of_item(def).is_none() {
|
||||
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def);
|
||||
|
||||
if !Q::in_qualifs(&qualifs) {
|
||||
return false;
|
||||
|
@ -828,7 +828,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
|
||||
let def = self.source.source.with_opt_param();
|
||||
let def = self.source.source.def_id();
|
||||
let mut rvalue = {
|
||||
let promoted = &mut self.promoted;
|
||||
let promoted_id = Promoted::new(next_promoted_id);
|
||||
@ -836,7 +836,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
let mut promoted_operand = |ty, span| {
|
||||
promoted.span = span;
|
||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
|
||||
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def));
|
||||
let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) };
|
||||
|
||||
Operand::Constant(Box::new(Constant {
|
||||
|
@ -488,12 +488,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante
|
||||
abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess);
|
||||
debug!("pretty printing THIR tree");
|
||||
for did in tcx.hir().body_owners() {
|
||||
let _ = writeln!(
|
||||
out,
|
||||
"{:?}:\n{}\n",
|
||||
did,
|
||||
tcx.thir_tree(ty::WithOptConstParam::unknown(did))
|
||||
);
|
||||
let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did));
|
||||
}
|
||||
out
|
||||
}
|
||||
@ -503,12 +498,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante
|
||||
abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess);
|
||||
debug!("pretty printing THIR flat");
|
||||
for did in tcx.hir().body_owners() {
|
||||
let _ = writeln!(
|
||||
out,
|
||||
"{:?}:\n{}\n",
|
||||
did,
|
||||
tcx.thir_flat(ty::WithOptConstParam::unknown(did))
|
||||
);
|
||||
let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
@ -420,7 +420,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||
// for generic arguments.
|
||||
tcx.type_of(param).subst_identity()
|
||||
}
|
||||
|
||||
Node::AnonConst(_) => {
|
||||
let parent_node = tcx.hir().get_parent(hir_id);
|
||||
match parent_node {
|
||||
|
@ -156,14 +156,6 @@ fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) {
|
||||
tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id));
|
||||
}
|
||||
|
||||
fn typeck_const_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(did, param_did): (LocalDefId, DefId),
|
||||
) -> &ty::TypeckResults<'tcx> {
|
||||
let fallback = move || tcx.type_of(param_did).subst_identity();
|
||||
typeck_with_fallback(tcx, did, fallback)
|
||||
}
|
||||
|
||||
fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
|
||||
let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity();
|
||||
typeck_with_fallback(tcx, def_id, fallback)
|
||||
@ -488,7 +480,6 @@ pub fn provide(providers: &mut Providers) {
|
||||
method::provide(providers);
|
||||
*providers = Providers {
|
||||
typeck_item_bodies,
|
||||
typeck_const_arg,
|
||||
typeck,
|
||||
diagnostic_only_typeck,
|
||||
has_typeck_results,
|
||||
|
@ -1500,7 +1500,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)),
|
||||
Ok(None) => {
|
||||
let tcx = self.tcx;
|
||||
let def_id = unevaluated.def.did;
|
||||
let def_id = unevaluated.def;
|
||||
span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
"unable to construct a constant value for the unevaluated constant {:?}",
|
||||
@ -1547,8 +1547,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
substs = replace_param_and_infer_substs_with_placeholder(tcx, substs);
|
||||
}
|
||||
} else {
|
||||
substs = InternalSubsts::identity_for_item(tcx, unevaluated.def.did);
|
||||
param_env = tcx.param_env(unevaluated.def.did);
|
||||
substs = InternalSubsts::identity_for_item(tcx, unevaluated.def);
|
||||
param_env = tcx.param_env(unevaluated.def);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -795,8 +795,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
|
||||
tcx.ensure().has_ffi_unwind_calls(def_id);
|
||||
|
||||
if tcx.hir().body_const_context(def_id).is_some() {
|
||||
tcx.ensure()
|
||||
.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(def_id));
|
||||
tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1539,8 +1539,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
|
||||
|
||||
let instance =
|
||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
|
||||
let instance = ty::InstanceDef::Item(def_id.to_def_id());
|
||||
let unused = tcx.unused_generic_params(instance);
|
||||
self.tables.unused_generic_params.set(def_id.local_def_index, unused);
|
||||
}
|
||||
|
@ -16,19 +16,16 @@ where
|
||||
{
|
||||
let def_ids = dump_mir_def_ids(tcx, single);
|
||||
|
||||
let mirs =
|
||||
def_ids
|
||||
.iter()
|
||||
.flat_map(|def_id| {
|
||||
if tcx.is_const_fn_raw(*def_id) {
|
||||
vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
|
||||
} else {
|
||||
vec![tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
|
||||
*def_id,
|
||||
)))]
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mirs = def_ids
|
||||
.iter()
|
||||
.flat_map(|def_id| {
|
||||
if tcx.is_const_fn_raw(*def_id) {
|
||||
vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
|
||||
} else {
|
||||
vec![tcx.instance_mir(ty::InstanceDef::Item(*def_id))]
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let use_subgraphs = mirs.len() > 1;
|
||||
if use_subgraphs {
|
||||
|
@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
span: Option<Span>,
|
||||
) -> EvalToConstValueResult<'tcx> {
|
||||
// Cannot resolve `Unevaluated` constants that contain inference
|
||||
// variables. We reject those here since `resolve_opt_const_arg`
|
||||
// variables. We reject those here since `resolve`
|
||||
// would fail otherwise.
|
||||
//
|
||||
// When trying to evaluate constants containing inference variables,
|
||||
@ -51,7 +51,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
bug!("did not expect inference variables here");
|
||||
}
|
||||
|
||||
match ty::Instance::resolve_opt_const_arg(
|
||||
match ty::Instance::resolve(
|
||||
self, param_env,
|
||||
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
|
||||
ct.def, ct.substs,
|
||||
@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
span: Option<Span>,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
// Cannot resolve `Unevaluated` constants that contain inference
|
||||
// variables. We reject those here since `resolve_opt_const_arg`
|
||||
// variables. We reject those here since `resolve`
|
||||
// would fail otherwise.
|
||||
//
|
||||
// When trying to evaluate constants containing inference variables,
|
||||
@ -82,7 +82,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
bug!("did not expect inference variables here");
|
||||
}
|
||||
|
||||
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
|
||||
match ty::Instance::resolve(self, param_env, ct.def, ct.substs) {
|
||||
Ok(Some(instance)) => {
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
|
||||
@ -94,14 +94,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
// used generic parameters is a bug of evaluation, so checking for it
|
||||
// here does feel somewhat sensible.
|
||||
if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
|
||||
assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
|
||||
let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
|
||||
assert!(matches!(self.def_kind(ct.def), DefKind::AnonConst));
|
||||
let mir_body = self.mir_for_ctfe(ct.def);
|
||||
if mir_body.is_polymorphic {
|
||||
let Some(local_def_id) = ct.def.did.as_local() else { return };
|
||||
let Some(local_def_id) = ct.def.as_local() else { return };
|
||||
self.struct_span_lint_hir(
|
||||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||
self.hir().local_def_id_to_hir_id(local_def_id),
|
||||
self.def_span(ct.def.did),
|
||||
self.def_span(ct.def),
|
||||
"cannot use constants which depend on generic parameters in types",
|
||||
|err| err,
|
||||
)
|
||||
|
@ -191,20 +191,13 @@ pub struct MirSource<'tcx> {
|
||||
|
||||
impl<'tcx> MirSource<'tcx> {
|
||||
pub fn item(def_id: DefId) -> Self {
|
||||
MirSource {
|
||||
instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
promoted: None,
|
||||
}
|
||||
MirSource { instance: InstanceDef::Item(def_id), promoted: None }
|
||||
}
|
||||
|
||||
pub fn from_instance(instance: InstanceDef<'tcx>) -> Self {
|
||||
MirSource { instance, promoted: None }
|
||||
}
|
||||
|
||||
pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
|
||||
self.instance.with_opt_param()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn def_id(&self) -> DefId {
|
||||
self.instance.def_id()
|
||||
@ -2436,16 +2429,6 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
Self::Val(val, ty)
|
||||
}
|
||||
|
||||
/// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
|
||||
/// converted to a constant, everything else becomes `Unevaluated`.
|
||||
pub fn from_anon_const(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Self {
|
||||
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env)
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug", ret)]
|
||||
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
@ -2485,28 +2468,25 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
|
||||
.substs;
|
||||
|
||||
let uneval = UnevaluatedConst {
|
||||
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
||||
substs,
|
||||
promoted: None,
|
||||
};
|
||||
let uneval = UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
|
||||
debug_assert!(!uneval.has_free_regions());
|
||||
|
||||
Self::Unevaluated(uneval, ty)
|
||||
}
|
||||
|
||||
/// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
|
||||
/// converted to a constant, everything else becomes `Unevaluated`.
|
||||
#[instrument(skip(tcx), level = "debug", ret)]
|
||||
fn from_opt_const_arg_anon_const(
|
||||
pub fn from_anon_const(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Self {
|
||||
let body_id = match tcx.hir().get_by_def_id(def.did) {
|
||||
let body_id = match tcx.hir().get_by_def_id(def) {
|
||||
hir::Node::AnonConst(ac) => ac.body,
|
||||
_ => span_bug!(
|
||||
tcx.def_span(def.did.to_def_id()),
|
||||
"from_anon_const can only process anonymous constants"
|
||||
),
|
||||
_ => {
|
||||
span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants")
|
||||
}
|
||||
};
|
||||
|
||||
let expr = &tcx.hir().body(body_id).value;
|
||||
@ -2522,7 +2502,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
};
|
||||
debug!("expr.kind: {:?}", expr.kind);
|
||||
|
||||
let ty = tcx.type_of(def.def_id_for_type_of()).subst_identity();
|
||||
let ty = tcx.type_of(def).subst_identity();
|
||||
debug!(?ty);
|
||||
|
||||
// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
|
||||
@ -2549,7 +2529,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||
let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id)
|
||||
&& let Some(parent_did) = parent_hir_id.as_owner()
|
||||
{
|
||||
@ -2559,15 +2539,14 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
};
|
||||
debug!(?parent_substs);
|
||||
|
||||
let did = def.did.to_def_id();
|
||||
let did = def.to_def_id();
|
||||
let child_substs = InternalSubsts::identity_for_item(tcx, did);
|
||||
let substs =
|
||||
tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter()));
|
||||
debug!(?substs);
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let span = tcx.hir().span(hir_id);
|
||||
let uneval = UnevaluatedConst::new(def.to_global(), substs);
|
||||
let span = tcx.def_span(def);
|
||||
let uneval = UnevaluatedConst::new(did, substs);
|
||||
debug!(?span, ?param_env);
|
||||
|
||||
match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
|
||||
@ -2581,8 +2560,8 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
// new unevaluated const and error hard later in codegen
|
||||
Self::Unevaluated(
|
||||
UnevaluatedConst {
|
||||
def: def.to_global(),
|
||||
substs: InternalSubsts::identity_for_item(tcx, def.did),
|
||||
def: did,
|
||||
substs: InternalSubsts::identity_for_item(tcx, did),
|
||||
promoted: None,
|
||||
},
|
||||
ty,
|
||||
@ -2607,7 +2586,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
|
||||
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub struct UnevaluatedConst<'tcx> {
|
||||
pub def: ty::WithOptConstParam<DefId>,
|
||||
pub def: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
pub promoted: Option<Promoted>,
|
||||
}
|
||||
@ -2623,10 +2602,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
|
||||
|
||||
impl<'tcx> UnevaluatedConst<'tcx> {
|
||||
#[inline]
|
||||
pub fn new(
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> UnevaluatedConst<'tcx> {
|
||||
pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> {
|
||||
UnevaluatedConst { def, substs, promoted: Default::default() }
|
||||
}
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ impl<'tcx> CodegenUnit<'tcx> {
|
||||
// instances into account. The others don't matter for
|
||||
// the codegen tests and can even make item order
|
||||
// unstable.
|
||||
InstanceDef::Item(def) => def.did.as_local().map(Idx::index),
|
||||
InstanceDef::Item(def) => def.as_local().map(Idx::index),
|
||||
InstanceDef::VTableShim(..)
|
||||
| InstanceDef::ReifyShim(..)
|
||||
| InstanceDef::Intrinsic(..)
|
||||
|
@ -298,8 +298,7 @@ pub fn write_mir_pretty<'tcx>(
|
||||
// are shared between mir_for_ctfe and optimized_mir
|
||||
write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?;
|
||||
} else {
|
||||
let instance_mir =
|
||||
tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)));
|
||||
let instance_mir = tcx.instance_mir(ty::InstanceDef::Item(def_id));
|
||||
render_body(w, instance_mir)?;
|
||||
}
|
||||
}
|
||||
@ -464,11 +463,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||
ConstantKind::Ty(ct) => match ct.kind() {
|
||||
ty::ConstKind::Param(p) => format!("Param({})", p),
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
format!(
|
||||
"Unevaluated({}, {:?})",
|
||||
self.tcx.def_path_str(uv.def.did),
|
||||
uv.substs,
|
||||
)
|
||||
format!("Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.substs,)
|
||||
}
|
||||
ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)),
|
||||
ty::ConstKind::Error(_) => "Error".to_string(),
|
||||
@ -481,7 +476,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||
ConstantKind::Unevaluated(uv, _) => {
|
||||
format!(
|
||||
"Unevaluated({}, {:?}, {:?})",
|
||||
self.tcx.def_path_str(uv.def.did),
|
||||
self.tcx.def_path_str(uv.def),
|
||||
uv.substs,
|
||||
uv.promoted,
|
||||
)
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Values computed by queries that use MIR.
|
||||
|
||||
use crate::mir::{Body, ConstantKind, Promoted};
|
||||
use crate::mir::ConstantKind;
|
||||
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::bit_set::BitMatrix;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_span::Span;
|
||||
@ -454,42 +454,3 @@ pub struct CoverageInfo {
|
||||
/// The total number of coverage region counter expressions added to the MIR `Body`.
|
||||
pub num_expressions: u32,
|
||||
}
|
||||
|
||||
/// Shims which make dealing with `WithOptConstParam` easier.
|
||||
///
|
||||
/// For more information on why this is needed, consider looking
|
||||
/// at the docs for `WithOptConstParam` itself.
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
#[inline]
|
||||
pub fn mir_const_qualif_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> ConstQualifs {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
self.mir_const_qualif_const_arg((def.did, param_did))
|
||||
} else {
|
||||
self.mir_const_qualif(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn promoted_mir_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
self.promoted_mir_of_const_arg((did, param_did))
|
||||
} else {
|
||||
self.promoted_mir(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'tcx Body<'tcx> {
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
self.mir_for_ctfe_of_const_arg((did, param_did))
|
||||
} else {
|
||||
self.mir_for_ctfe(def.did)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,14 +174,6 @@ impl AsLocalKey for DefId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for ty::WithOptConstParam<LocalDefId> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.did.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for SimplifiedType {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
@ -313,7 +305,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
(self.0).def.did.default_span(tcx)
|
||||
(self.0).def.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,26 +369,24 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
/// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
|
||||
query thir_body(key: ty::WithOptConstParam<LocalDefId>)
|
||||
-> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed>
|
||||
{
|
||||
query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
|
||||
// Perf tests revealed that hashing THIR is inefficient (see #85729).
|
||||
no_hash
|
||||
desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Create a THIR tree for debugging.
|
||||
query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String {
|
||||
query thir_tree(key: LocalDefId) -> &'tcx String {
|
||||
no_hash
|
||||
arena_cache
|
||||
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Create a list-like THIR representation for debugging.
|
||||
query thir_flat(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String {
|
||||
query thir_flat(key: LocalDefId) -> &'tcx String {
|
||||
no_hash
|
||||
arena_cache
|
||||
desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Set of all the `DefId`s in this crate that have MIR associated with
|
||||
@ -407,31 +405,19 @@ rustc_queries! {
|
||||
cache_on_disk_if { key.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
query mir_const_qualif_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> mir::ConstQualifs {
|
||||
desc {
|
||||
|tcx| "const checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the MIR for a given `DefId` right after it's built - this includes
|
||||
/// unreachable code.
|
||||
query mir_built(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Fetch the MIR for a given `DefId` up till the point where it is
|
||||
/// ready for const qualification.
|
||||
///
|
||||
/// See the README for the `mir` module for details.
|
||||
query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc {
|
||||
|tcx| "preparing {}`{}` for borrow checking",
|
||||
if key.const_param_did.is_some() { "the const argument " } else { "" },
|
||||
tcx.def_path_str(key.did.to_def_id()),
|
||||
}
|
||||
query mir_const(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key.to_def_id()) }
|
||||
no_hash
|
||||
}
|
||||
|
||||
@ -444,22 +430,10 @@ rustc_queries! {
|
||||
}
|
||||
separate_provide_extern
|
||||
}
|
||||
/// Try to build an abstract representation of the given constant.
|
||||
query thir_abstract_const_of_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> {
|
||||
desc {
|
||||
|tcx|
|
||||
"building an abstract representation for the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id()),
|
||||
}
|
||||
}
|
||||
|
||||
query mir_drops_elaborated_and_const_checked(
|
||||
key: ty::WithOptConstParam<LocalDefId>
|
||||
) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
no_hash
|
||||
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
query mir_for_ctfe(
|
||||
@ -470,24 +444,12 @@ rustc_queries! {
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
||||
desc {
|
||||
|tcx| "caching MIR for CTFE of the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
query mir_promoted(key: ty::WithOptConstParam<LocalDefId>) ->
|
||||
(
|
||||
&'tcx Steal<mir::Body<'tcx>>,
|
||||
&'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
|
||||
) {
|
||||
query mir_promoted(key: LocalDefId) -> (
|
||||
&'tcx Steal<mir::Body<'tcx>>,
|
||||
&'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
|
||||
) {
|
||||
no_hash
|
||||
desc {
|
||||
|tcx| "processing MIR for {}`{}`",
|
||||
if key.const_param_did.is_some() { "the const argument " } else { "" },
|
||||
tcx.def_path_str(key.did.to_def_id()),
|
||||
}
|
||||
desc { |tcx| "processing MIR for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> {
|
||||
@ -544,14 +506,6 @@ rustc_queries! {
|
||||
cache_on_disk_if { key.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
query promoted_mir_of_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
|
||||
desc {
|
||||
|tcx| "optimizing promoted MIR for the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Erases regions from `ty` to yield a new type.
|
||||
/// Normally you would just use `tcx.erase_regions(value)`,
|
||||
@ -840,12 +794,6 @@ rustc_queries! {
|
||||
desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query unsafety_check_result_for_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::UnsafetyCheckResult {
|
||||
desc {
|
||||
|tcx| "unsafety-checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be
|
||||
/// used with `-Zthir-unsafeck`.
|
||||
@ -853,12 +801,6 @@ rustc_queries! {
|
||||
desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query thir_check_unsafety_for_const_arg(key: (LocalDefId, DefId)) {
|
||||
desc {
|
||||
|tcx| "unsafety-checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the types assumed to be well formed while "inside" of the given item.
|
||||
///
|
||||
@ -960,14 +902,6 @@ rustc_queries! {
|
||||
desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query typeck_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> &'tcx ty::TypeckResults<'tcx> {
|
||||
desc {
|
||||
|tcx| "type-checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id()),
|
||||
}
|
||||
}
|
||||
query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
|
||||
desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
@ -992,12 +926,6 @@ rustc_queries! {
|
||||
desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
|
||||
}
|
||||
query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> {
|
||||
desc {
|
||||
|tcx| "borrow-checking the const argument`{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a complete map from all types to their inherent impls.
|
||||
/// Not meant to be used directly outside of coherence.
|
||||
@ -2117,15 +2045,6 @@ rustc_queries! {
|
||||
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
||||
}
|
||||
|
||||
query resolve_instance_of_const_arg(
|
||||
key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>
|
||||
) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
|
||||
desc {
|
||||
"resolving instance of the const argument `{}`",
|
||||
ty::Instance::new(key.value.0.to_def_id(), key.value.2),
|
||||
}
|
||||
}
|
||||
|
||||
query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
desc { "revealing opaque types in `{:?}`", key }
|
||||
}
|
||||
|
@ -929,8 +929,8 @@ mod size_asserts {
|
||||
static_assert_size!(Block, 56);
|
||||
static_assert_size!(Expr<'_>, 64);
|
||||
static_assert_size!(ExprKind<'_>, 40);
|
||||
static_assert_size!(Pat<'_>, 72);
|
||||
static_assert_size!(PatKind<'_>, 56);
|
||||
static_assert_size!(Pat<'_>, 64);
|
||||
static_assert_size!(PatKind<'_>, 48);
|
||||
static_assert_size!(Stmt<'_>, 56);
|
||||
static_assert_size!(StmtKind<'_>, 48);
|
||||
// tidy-alphabetical-end
|
||||
|
@ -36,15 +36,8 @@ pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>,
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Returns a const without substs applied
|
||||
pub fn bound_abstract_const(
|
||||
self,
|
||||
uv: ty::WithOptConstParam<DefId>,
|
||||
) -> BoundAbstractConst<'tcx> {
|
||||
let ac = if let Some((did, param_did)) = uv.as_const_arg() {
|
||||
self.thir_abstract_const_of_const_arg((did, param_did))
|
||||
} else {
|
||||
self.thir_abstract_const(uv.did)
|
||||
};
|
||||
pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> {
|
||||
let ac = self.thir_abstract_const(uv);
|
||||
Ok(ac?.map(|ac| EarlyBinder(ac)))
|
||||
}
|
||||
|
||||
|
@ -53,19 +53,12 @@ impl<'tcx> Const<'tcx> {
|
||||
|
||||
/// Literals and const generic parameters are eagerly converted to a constant, everything else
|
||||
/// becomes `Unevaluated`.
|
||||
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
||||
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub fn from_opt_const_arg_anon_const(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> Self {
|
||||
let body_id = match tcx.hir().get_by_def_id(def.did) {
|
||||
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
|
||||
let body_id = match tcx.hir().get_by_def_id(def) {
|
||||
hir::Node::AnonConst(ac) => ac.body,
|
||||
_ => span_bug!(
|
||||
tcx.def_span(def.did.to_def_id()),
|
||||
tcx.def_span(def.to_def_id()),
|
||||
"from_anon_const can only process anonymous constants"
|
||||
),
|
||||
};
|
||||
@ -73,17 +66,14 @@ impl<'tcx> Const<'tcx> {
|
||||
let expr = &tcx.hir().body(body_id).value;
|
||||
debug!(?expr);
|
||||
|
||||
let ty = tcx
|
||||
.type_of(def.def_id_for_type_of())
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic");
|
||||
let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic");
|
||||
|
||||
match Self::try_eval_lit_or_param(tcx, ty, expr) {
|
||||
Some(v) => v,
|
||||
None => tcx.mk_const(
|
||||
ty::UnevaluatedConst {
|
||||
def: def.to_global(),
|
||||
substs: InternalSubsts::identity_for_item(tcx, def.did),
|
||||
def: def.to_def_id(),
|
||||
substs: InternalSubsts::identity_for_item(tcx, def.to_def_id()),
|
||||
},
|
||||
ty,
|
||||
),
|
||||
|
@ -17,7 +17,7 @@ use super::ScalarInt;
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
|
||||
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub struct UnevaluatedConst<'tcx> {
|
||||
pub def: ty::WithOptConstParam<DefId>,
|
||||
pub def: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
}
|
||||
|
||||
@ -36,10 +36,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
|
||||
|
||||
impl<'tcx> UnevaluatedConst<'tcx> {
|
||||
#[inline]
|
||||
pub fn new(
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> UnevaluatedConst<'tcx> {
|
||||
pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> {
|
||||
UnevaluatedConst { def, substs }
|
||||
}
|
||||
}
|
||||
@ -224,9 +221,9 @@ impl<'tcx> ConstKind<'tcx> {
|
||||
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
|
||||
// we can call `infcx.const_eval_resolve` which handles inference variables.
|
||||
let param_env_and = if (param_env, unevaluated).has_non_region_infer() {
|
||||
tcx.param_env(unevaluated.def.did).and(ty::UnevaluatedConst {
|
||||
tcx.param_env(unevaluated.def).and(ty::UnevaluatedConst {
|
||||
def: unevaluated.def,
|
||||
substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did),
|
||||
substs: InternalSubsts::identity_for_item(tcx, unevaluated.def),
|
||||
})
|
||||
} else {
|
||||
tcx.erase_regions(param_env)
|
||||
|
@ -13,7 +13,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use crate::middle::resolve_bound_vars;
|
||||
use crate::middle::stability;
|
||||
use crate::mir::interpret::{self, Allocation, ConstAllocation};
|
||||
use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted};
|
||||
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
|
||||
use crate::query::LocalCrate;
|
||||
use crate::thir::Thir;
|
||||
use crate::traits;
|
||||
@ -24,7 +24,7 @@ use crate::ty::{
|
||||
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
|
||||
GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
|
||||
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions,
|
||||
TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, Visibility,
|
||||
TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
|
||||
};
|
||||
use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
|
||||
use rustc_ast::{self as ast, attr};
|
||||
@ -591,28 +591,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn typeck_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx TypeckResults<'tcx> {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
self.typeck_const_arg((def.did, param_did))
|
||||
} else {
|
||||
self.typeck(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mir_borrowck_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx BorrowCheckResult<'tcx> {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
self.mir_borrowck_const_arg((def.did, param_did))
|
||||
} else {
|
||||
self.mir_borrowck(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
|
||||
self.arena.alloc(Steal::new(thir))
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub enum InstanceDef<'tcx> {
|
||||
/// - `fn` items
|
||||
/// - closures
|
||||
/// - generators
|
||||
Item(ty::WithOptConstParam<DefId>),
|
||||
Item(DefId),
|
||||
|
||||
/// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
|
||||
///
|
||||
@ -143,7 +143,7 @@ impl<'tcx> Instance<'tcx> {
|
||||
|
||||
match self.def {
|
||||
InstanceDef::Item(def) => tcx
|
||||
.upstream_monomorphizations_for(def.did)
|
||||
.upstream_monomorphizations_for(def)
|
||||
.and_then(|monos| monos.get(&self.substs).cloned()),
|
||||
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
|
||||
_ => None,
|
||||
@ -155,8 +155,8 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
#[inline]
|
||||
pub fn def_id(self) -> DefId {
|
||||
match self {
|
||||
InstanceDef::Item(def) => def.did,
|
||||
InstanceDef::VTableShim(def_id)
|
||||
InstanceDef::Item(def_id)
|
||||
| InstanceDef::VTableShim(def_id)
|
||||
| InstanceDef::ReifyShim(def_id)
|
||||
| InstanceDef::FnPtrShim(def_id, _)
|
||||
| InstanceDef::Virtual(def_id, _)
|
||||
@ -172,7 +172,7 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
/// Returns the `DefId` of instances which might not require codegen locally.
|
||||
pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
|
||||
match self {
|
||||
ty::InstanceDef::Item(def) => Some(def.did),
|
||||
ty::InstanceDef::Item(def) => Some(def),
|
||||
ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => {
|
||||
Some(def_id)
|
||||
}
|
||||
@ -188,23 +188,6 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
|
||||
match self {
|
||||
InstanceDef::Item(def) => def,
|
||||
InstanceDef::VTableShim(def_id)
|
||||
| InstanceDef::ReifyShim(def_id)
|
||||
| InstanceDef::FnPtrShim(def_id, _)
|
||||
| InstanceDef::Virtual(def_id, _)
|
||||
| InstanceDef::Intrinsic(def_id)
|
||||
| InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
|
||||
| InstanceDef::DropGlue(def_id, _)
|
||||
| InstanceDef::CloneShim(def_id, _)
|
||||
| InstanceDef::ThreadLocalShim(def_id)
|
||||
| InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_attrs(
|
||||
&self,
|
||||
@ -222,7 +205,7 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
let def_id = match *self {
|
||||
ty::InstanceDef::Item(def) => def.did,
|
||||
ty::InstanceDef::Item(def) => def,
|
||||
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
|
||||
ty::InstanceDef::ThreadLocalShim(_) => return false,
|
||||
_ => return true,
|
||||
@ -273,8 +256,7 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
|
||||
pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
match *self {
|
||||
InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. })
|
||||
| InstanceDef::Virtual(def_id, _) => {
|
||||
InstanceDef::Item(def_id) | InstanceDef::Virtual(def_id, _) => {
|
||||
tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
|
||||
}
|
||||
InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
|
||||
@ -358,7 +340,7 @@ impl<'tcx> Instance<'tcx> {
|
||||
def_id,
|
||||
substs
|
||||
);
|
||||
Instance { def: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs }
|
||||
Instance { def: InstanceDef::Item(def_id), substs }
|
||||
}
|
||||
|
||||
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||
@ -403,18 +385,21 @@ impl<'tcx> Instance<'tcx> {
|
||||
/// couldn't complete due to errors elsewhere - this is distinct
|
||||
/// from `Ok(None)` to avoid misleading diagnostics when an error
|
||||
/// has already been/will be emitted, for the original cause
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
pub fn resolve(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
Instance::resolve_opt_const_arg(
|
||||
tcx,
|
||||
param_env,
|
||||
ty::WithOptConstParam::unknown(def_id),
|
||||
substs,
|
||||
)
|
||||
// All regions in the result of this query are erased, so it's
|
||||
// fine to erase all of the input regions.
|
||||
|
||||
// HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
|
||||
// below is more likely to ignore the bounds in scope (e.g. if the only
|
||||
// generic parameters mentioned by `substs` were lifetime ones).
|
||||
let substs = tcx.erase_regions(substs);
|
||||
tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, substs))))
|
||||
}
|
||||
|
||||
pub fn expect_resolve(
|
||||
@ -432,31 +417,6 @@ impl<'tcx> Instance<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// This should be kept up to date with `resolve`.
|
||||
pub fn resolve_opt_const_arg(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
// All regions in the result of this query are erased, so it's
|
||||
// fine to erase all of the input regions.
|
||||
|
||||
// HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
|
||||
// below is more likely to ignore the bounds in scope (e.g. if the only
|
||||
// generic parameters mentioned by `substs` were lifetime ones).
|
||||
let substs = tcx.erase_regions(substs);
|
||||
|
||||
// FIXME(eddyb) should this always use `param_env.with_reveal_all()`?
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
tcx.resolve_instance_of_const_arg(
|
||||
tcx.erase_regions(param_env.and((did, param_did, substs))),
|
||||
)
|
||||
} else {
|
||||
tcx.resolve_instance(tcx.erase_regions(param_env.and((def.did, substs))))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_for_fn_ptr(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -470,7 +430,7 @@ impl<'tcx> Instance<'tcx> {
|
||||
match resolved.def {
|
||||
InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
|
||||
debug!(" => fn pointer created for function with #[track_caller]");
|
||||
resolved.def = InstanceDef::ReifyShim(def.did);
|
||||
resolved.def = InstanceDef::ReifyShim(def);
|
||||
}
|
||||
InstanceDef::Virtual(def_id, _) => {
|
||||
debug!(" => fn pointer created for virtual call");
|
||||
@ -513,23 +473,23 @@ impl<'tcx> Instance<'tcx> {
|
||||
if resolved.def.requires_caller_location(tcx)
|
||||
// 2) The caller location parameter comes from having `#[track_caller]`
|
||||
// on the implementation, and *not* on the trait method.
|
||||
&& !tcx.should_inherit_track_caller(def.did)
|
||||
&& !tcx.should_inherit_track_caller(def)
|
||||
// If the method implementation comes from the trait definition itself
|
||||
// (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
|
||||
// then we don't need to generate a shim. This check is needed because
|
||||
// `should_inherit_track_caller` returns `false` if our method
|
||||
// implementation comes from the trait block, and not an impl block
|
||||
&& !matches!(
|
||||
tcx.opt_associated_item(def.did),
|
||||
tcx.opt_associated_item(def),
|
||||
Some(ty::AssocItem {
|
||||
container: ty::AssocItemContainer::TraitContainer,
|
||||
..
|
||||
})
|
||||
)
|
||||
{
|
||||
if tcx.is_closure(def.did) {
|
||||
if tcx.is_closure(def) {
|
||||
debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
|
||||
def.did, def_id, substs);
|
||||
def, def_id, substs);
|
||||
|
||||
// Create a shim for the `FnOnce/FnMut/Fn` method we are calling
|
||||
// - unlike functions, invoking a closure always goes through a
|
||||
@ -537,9 +497,9 @@ impl<'tcx> Instance<'tcx> {
|
||||
resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs };
|
||||
} else {
|
||||
debug!(
|
||||
" => vtable fn pointer created for function with #[track_caller]: {:?}", def.did
|
||||
" => vtable fn pointer created for function with #[track_caller]: {:?}", def
|
||||
);
|
||||
resolved.def = InstanceDef::ReifyShim(def.did);
|
||||
resolved.def = InstanceDef::ReifyShim(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -714,11 +674,8 @@ fn polymorphize<'tcx>(
|
||||
debug!("fold_ty: ty={:?}", ty);
|
||||
match *ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
let polymorphized_substs = polymorphize(
|
||||
self.tcx,
|
||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
substs,
|
||||
);
|
||||
let polymorphized_substs =
|
||||
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
|
||||
if substs == polymorphized_substs {
|
||||
ty
|
||||
} else {
|
||||
@ -726,11 +683,8 @@ fn polymorphize<'tcx>(
|
||||
}
|
||||
}
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
let polymorphized_substs = polymorphize(
|
||||
self.tcx,
|
||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
substs,
|
||||
);
|
||||
let polymorphized_substs =
|
||||
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
|
||||
if substs == polymorphized_substs {
|
||||
ty
|
||||
} else {
|
||||
|
@ -1007,7 +1007,7 @@ impl<'tcx> Term<'tcx> {
|
||||
_ => None,
|
||||
},
|
||||
TermKind::Const(ct) => match ct.kind() {
|
||||
ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def.did, uv.substs)),
|
||||
ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def, uv.substs)),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
@ -1471,129 +1471,6 @@ pub struct BoundConst<'tcx> {
|
||||
|
||||
pub type PlaceholderConst<'tcx> = Placeholder<BoundVar>;
|
||||
|
||||
/// A `DefId` which, in case it is a const argument, is potentially bundled with
|
||||
/// the `DefId` of the generic parameter it instantiates.
|
||||
///
|
||||
/// This is used to avoid calls to `type_of` for const arguments during typeck
|
||||
/// which cause cycle errors.
|
||||
///
|
||||
/// ```rust
|
||||
/// struct A;
|
||||
/// impl A {
|
||||
/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] }
|
||||
/// // ^ const parameter
|
||||
/// }
|
||||
/// struct B;
|
||||
/// impl B {
|
||||
/// fn foo<const M: u8>(&self) -> usize { 42 }
|
||||
/// // ^ const parameter
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let a = A;
|
||||
/// let _b = a.foo::<{ 3 + 7 }>();
|
||||
/// // ^^^^^^^^^ const argument
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Let's look at the call `a.foo::<{ 3 + 7 }>()` here. We do not know
|
||||
/// which `foo` is used until we know the type of `a`.
|
||||
///
|
||||
/// We only know the type of `a` once we are inside of `typeck(main)`.
|
||||
/// We also end up normalizing the type of `_b` during `typeck(main)` which
|
||||
/// requires us to evaluate the const argument.
|
||||
///
|
||||
/// To evaluate that const argument we need to know its type,
|
||||
/// which we would get using `type_of(const_arg)`. This requires us to
|
||||
/// resolve `foo` as it can be either `usize` or `u8` in this example.
|
||||
/// However, resolving `foo` once again requires `typeck(main)` to get the type of `a`,
|
||||
/// which results in a cycle.
|
||||
///
|
||||
/// In short we must not call `type_of(const_arg)` during `typeck(main)`.
|
||||
///
|
||||
/// When first creating the `ty::Const` of the const argument inside of `typeck` we have
|
||||
/// already resolved `foo` so we know which const parameter this argument instantiates.
|
||||
/// This means that we also know the expected result of `type_of(const_arg)` even if we
|
||||
/// aren't allowed to call that query: it is equal to `type_of(const_param)` which is
|
||||
/// trivial to compute.
|
||||
///
|
||||
/// If we now want to use that constant in a place which potentially needs its type
|
||||
/// we also pass the type of its `const_param`. This is the point of `WithOptConstParam`,
|
||||
/// except that instead of a `Ty` we bundle the `DefId` of the const parameter.
|
||||
/// Meaning that we need to use `type_of(const_param_did)` if `const_param_did` is `Some`
|
||||
/// to get the type of `did`.
|
||||
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Hash, HashStable)]
|
||||
pub struct WithOptConstParam<T> {
|
||||
pub did: T,
|
||||
/// The `DefId` of the corresponding generic parameter in case `did` is
|
||||
/// a const argument.
|
||||
///
|
||||
/// Note that even if `did` is a const argument, this may still be `None`.
|
||||
/// All queries taking `WithOptConstParam` start by calling `tcx.opt_const_param_of(def.did)`
|
||||
/// to potentially update `param_did` in the case it is `None`.
|
||||
pub const_param_did: Option<DefId>,
|
||||
}
|
||||
|
||||
impl<T> WithOptConstParam<T> {
|
||||
/// Creates a new `WithOptConstParam` setting `const_param_did` to `None`.
|
||||
#[inline(always)]
|
||||
pub fn unknown(did: T) -> WithOptConstParam<T> {
|
||||
WithOptConstParam { did, const_param_did: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl WithOptConstParam<LocalDefId> {
|
||||
/// Returns `Some((did, param_did))` if `def_id` is a const argument,
|
||||
/// `None` otherwise.
|
||||
#[inline(always)]
|
||||
pub fn try_lookup(_: LocalDefId, _: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> {
|
||||
None
|
||||
}
|
||||
|
||||
/// In case `self` is unknown but `self.did` is a const argument, this returns
|
||||
/// a `WithOptConstParam` with the correct `const_param_did`.
|
||||
#[inline(always)]
|
||||
pub fn try_upgrade(self, _: TyCtxt<'_>) -> Option<WithOptConstParam<LocalDefId>> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn to_global(self) -> WithOptConstParam<DefId> {
|
||||
WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did }
|
||||
}
|
||||
|
||||
pub fn def_id_for_type_of(self) -> DefId {
|
||||
self.did.to_def_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl WithOptConstParam<DefId> {
|
||||
pub fn as_local(self) -> Option<WithOptConstParam<LocalDefId>> {
|
||||
self.did
|
||||
.as_local()
|
||||
.map(|did| WithOptConstParam { did, const_param_did: self.const_param_did })
|
||||
}
|
||||
|
||||
pub fn as_const_arg(self) -> Option<(LocalDefId, DefId)> {
|
||||
if let Some(param_did) = self.const_param_did {
|
||||
if let Some(did) = self.did.as_local() {
|
||||
return Some((did, param_did));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn is_local(self) -> bool {
|
||||
self.did.is_local()
|
||||
}
|
||||
|
||||
pub fn def_id_for_type_of(self) -> DefId {
|
||||
self.const_param_did.unwrap_or(self.did)
|
||||
}
|
||||
}
|
||||
|
||||
/// When type checking, we use the `ParamEnv` to track
|
||||
/// details about the set of where-clauses that are in scope at this
|
||||
/// particular point.
|
||||
@ -2361,7 +2238,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
match instance {
|
||||
ty::InstanceDef::Item(def) => {
|
||||
debug!("calling def_kind on def: {:?}", def);
|
||||
let def_kind = self.def_kind(def.did);
|
||||
let def_kind = self.def_kind(def);
|
||||
debug!("returned from def_kind: {:?}", def_kind);
|
||||
match def_kind {
|
||||
DefKind::Const
|
||||
@ -2369,13 +2246,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
| DefKind::AssocConst
|
||||
| DefKind::Ctor(..)
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst => self.mir_for_ctfe_opt_const_arg(def),
|
||||
| DefKind::InlineConst => self.mir_for_ctfe(def),
|
||||
// If the caller wants `mir_for_ctfe` of a function they should not be using
|
||||
// `instance_mir`, so we'll assume const fn also wants the optimized version.
|
||||
_ => {
|
||||
assert_eq!(def.const_param_did, None);
|
||||
self.optimized_mir(def.did)
|
||||
}
|
||||
_ => self.optimized_mir(def),
|
||||
}
|
||||
}
|
||||
ty::InstanceDef::VTableShim(..)
|
||||
|
@ -1328,13 +1328,13 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
|
||||
match self.tcx().def_kind(def.did) {
|
||||
match self.tcx().def_kind(def) {
|
||||
DefKind::Const | DefKind::AssocConst => {
|
||||
p!(print_value_path(def.did, substs))
|
||||
p!(print_value_path(def, substs))
|
||||
}
|
||||
DefKind::AnonConst => {
|
||||
if def.is_local()
|
||||
&& let span = self.tcx().def_span(def.did)
|
||||
&& let span = self.tcx().def_span(def)
|
||||
&& let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
|
||||
{
|
||||
p!(write("{}", snip))
|
||||
@ -1344,7 +1344,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
// cause printing to enter an infinite recursion if the anon const is in the self type i.e.
|
||||
// `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {`
|
||||
// where we would try to print `<[T; /* print `constant#0` again */] as Default>::{constant#0}`
|
||||
p!(write("{}::{}", self.tcx().crate_name(def.did.krate), self.tcx().def_path(def.did).to_string_no_crate_verbose()))
|
||||
p!(write("{}::{}", self.tcx().crate_name(def.krate), self.tcx().def_path(def).to_string_no_crate_verbose()))
|
||||
}
|
||||
}
|
||||
defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind),
|
||||
|
@ -78,7 +78,7 @@ pub fn as_constant_inner<'tcx>(
|
||||
ExprKind::NamedConst { def_id, substs, ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().and_then(push_cuta);
|
||||
|
||||
let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||
let uneval = mir::UnevaluatedConst::new(def_id, substs);
|
||||
let literal = ConstantKind::Unevaluated(uneval, ty);
|
||||
|
||||
Constant { user_ty, span, literal }
|
||||
@ -90,7 +90,7 @@ pub fn as_constant_inner<'tcx>(
|
||||
Constant { user_ty: None, span, literal }
|
||||
}
|
||||
ExprKind::ConstBlock { did: def_id, substs } => {
|
||||
let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||
let uneval = mir::UnevaluatedConst::new(def_id, substs);
|
||||
let literal = ConstantKind::Unevaluated(uneval, ty);
|
||||
|
||||
Constant { user_ty: None, span, literal }
|
||||
|
@ -32,38 +32,20 @@ use super::lints;
|
||||
|
||||
pub(crate) fn mir_built(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def: LocalDefId,
|
||||
) -> &rustc_data_structures::steal::Steal<Body<'_>> {
|
||||
if let Some(def) = def.try_upgrade(tcx) {
|
||||
return tcx.mir_built(def);
|
||||
}
|
||||
|
||||
let mut body = mir_build(tcx, def);
|
||||
if def.const_param_did.is_some() {
|
||||
assert!(matches!(body.source.instance, ty::InstanceDef::Item(_)));
|
||||
body.source = MirSource::from_instance(ty::InstanceDef::Item(def.to_global()));
|
||||
}
|
||||
|
||||
tcx.alloc_steal_mir(body)
|
||||
tcx.alloc_steal_mir(mir_build(tcx, def))
|
||||
}
|
||||
|
||||
/// Construct the MIR for a given `DefId`.
|
||||
fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||
fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
|
||||
// Ensure unsafeck and abstract const building is ran before we steal the THIR.
|
||||
match def {
|
||||
ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => {
|
||||
tcx.ensure_with_value().thir_check_unsafety_for_const_arg((did, const_param_did));
|
||||
tcx.ensure_with_value().thir_abstract_const_of_const_arg((did, const_param_did));
|
||||
}
|
||||
ty::WithOptConstParam { did, const_param_did: None } => {
|
||||
tcx.ensure_with_value().thir_check_unsafety(did);
|
||||
tcx.ensure_with_value().thir_abstract_const(did);
|
||||
tcx.ensure_with_value().check_match(did);
|
||||
}
|
||||
}
|
||||
tcx.ensure_with_value().thir_check_unsafety(def);
|
||||
tcx.ensure_with_value().thir_abstract_const(def);
|
||||
tcx.ensure_with_value().check_match(def);
|
||||
|
||||
let body = match tcx.thir_body(def) {
|
||||
Err(error_reported) => construct_error(tcx, def.did, error_reported),
|
||||
Err(error_reported) => construct_error(tcx, def, error_reported),
|
||||
Ok((thir, expr)) => {
|
||||
// We ran all queries that depended on THIR at the beginning
|
||||
// of `mir_build`, so now we can steal it
|
||||
@ -161,8 +143,7 @@ struct Builder<'a, 'tcx> {
|
||||
thir: &'a Thir<'tcx>,
|
||||
cfg: CFG<'tcx>,
|
||||
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def_id: DefId,
|
||||
def_id: LocalDefId,
|
||||
hir_id: hir::HirId,
|
||||
parent_module: DefId,
|
||||
check_overflow: bool,
|
||||
@ -428,26 +409,26 @@ macro_rules! unpack {
|
||||
|
||||
fn construct_fn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fn_def: ty::WithOptConstParam<LocalDefId>,
|
||||
fn_def: LocalDefId,
|
||||
thir: &Thir<'tcx>,
|
||||
expr: ExprId,
|
||||
fn_sig: ty::FnSig<'tcx>,
|
||||
) -> Body<'tcx> {
|
||||
let span = tcx.def_span(fn_def.did);
|
||||
let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did);
|
||||
let generator_kind = tcx.generator_kind(fn_def.did);
|
||||
let span = tcx.def_span(fn_def);
|
||||
let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def);
|
||||
let generator_kind = tcx.generator_kind(fn_def);
|
||||
|
||||
// The representation of thir for `-Zunpretty=thir-tree` relies on
|
||||
// the entry expression being the last element of `thir.exprs`.
|
||||
assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
|
||||
|
||||
// Figure out what primary body this item has.
|
||||
let body_id = tcx.hir().body_owned_by(fn_def.did);
|
||||
let body_id = tcx.hir().body_owned_by(fn_def);
|
||||
let span_with_body = tcx.hir().span_with_body(fn_id);
|
||||
let return_ty_span = tcx
|
||||
.hir()
|
||||
.fn_decl_by_hir_id(fn_id)
|
||||
.unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def.did))
|
||||
.unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def))
|
||||
.output
|
||||
.span();
|
||||
|
||||
@ -457,7 +438,7 @@ fn construct_fn<'tcx>(
|
||||
};
|
||||
|
||||
let mut abi = fn_sig.abi;
|
||||
if let DefKind::Closure = tcx.def_kind(fn_def.did) {
|
||||
if let DefKind::Closure = tcx.def_kind(fn_def) {
|
||||
// HACK(eddyb) Avoid having RustCall on closures,
|
||||
// as it adds unnecessary (and wrong) auto-tupling.
|
||||
abi = Abi::Rust;
|
||||
@ -483,7 +464,7 @@ fn construct_fn<'tcx>(
|
||||
{
|
||||
return custom::build_custom_mir(
|
||||
tcx,
|
||||
fn_def.did.to_def_id(),
|
||||
fn_def.to_def_id(),
|
||||
fn_id,
|
||||
thir,
|
||||
expr,
|
||||
@ -547,12 +528,12 @@ fn construct_fn<'tcx>(
|
||||
|
||||
fn construct_const<'a, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def: LocalDefId,
|
||||
thir: &'a Thir<'tcx>,
|
||||
expr: ExprId,
|
||||
const_ty: Ty<'tcx>,
|
||||
) -> Body<'tcx> {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||
|
||||
// Figure out what primary body this item has.
|
||||
let (span, const_ty_span) = match tcx.hir().get(hir_id) {
|
||||
@ -568,10 +549,10 @@ fn construct_const<'a, 'tcx>(
|
||||
..
|
||||
}) => (*span, ty.span),
|
||||
Node::AnonConst(_) => {
|
||||
let span = tcx.def_span(def.did);
|
||||
let span = tcx.def_span(def);
|
||||
(span, span)
|
||||
}
|
||||
_ => span_bug!(tcx.def_span(def.did), "can't build MIR for {:?}", def.did),
|
||||
_ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def),
|
||||
};
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
@ -669,7 +650,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn new(
|
||||
thir: &'a Thir<'tcx>,
|
||||
infcx: InferCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def: LocalDefId,
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
arg_count: usize,
|
||||
@ -688,20 +669,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
check_overflow |= tcx.sess.overflow_checks();
|
||||
// Constants always need overflow checks.
|
||||
check_overflow |= matches!(
|
||||
tcx.hir().body_owner_kind(def.did),
|
||||
tcx.hir().body_owner_kind(def),
|
||||
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_)
|
||||
);
|
||||
|
||||
let lint_level = LintLevel::Explicit(hir_id);
|
||||
let param_env = tcx.param_env(def.did);
|
||||
let param_env = tcx.param_env(def);
|
||||
let mut builder = Builder {
|
||||
thir,
|
||||
tcx,
|
||||
infcx,
|
||||
region_scope_tree: tcx.region_scope_tree(def.did),
|
||||
region_scope_tree: tcx.region_scope_tree(def),
|
||||
param_env,
|
||||
def,
|
||||
def_id: def.did.to_def_id(),
|
||||
def_id: def,
|
||||
hir_id,
|
||||
parent_module: tcx.parent_module(hir_id).to_def_id(),
|
||||
check_overflow,
|
||||
@ -741,7 +721,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
Body::new(
|
||||
MirSource::item(self.def_id),
|
||||
MirSource::item(self.def_id.to_def_id()),
|
||||
self.cfg.basic_blocks,
|
||||
self.source_scopes,
|
||||
self.local_decls,
|
||||
@ -779,7 +759,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
let tcx = self.tcx;
|
||||
self.upvars = tcx
|
||||
.closure_captures(self.def.did)
|
||||
.closure_captures(self.def_id)
|
||||
.iter()
|
||||
.zip(capture_tys)
|
||||
.enumerate()
|
||||
|
@ -117,10 +117,10 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||
}
|
||||
|
||||
/// Handle closures/generators/inline-consts, which is unsafecked with their parent body.
|
||||
fn visit_inner_body(&mut self, def: ty::WithOptConstParam<LocalDefId>) {
|
||||
fn visit_inner_body(&mut self, def: LocalDefId) {
|
||||
if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
|
||||
let inner_thir = &inner_thir.borrow();
|
||||
let hir_context = self.tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let hir_context = self.tcx.hir().local_def_id_to_hir_id(def);
|
||||
let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self };
|
||||
inner_visitor.visit_expr(&inner_thir[expr]);
|
||||
// Unsafe blocks can be used in the inner body, make sure to take it into account
|
||||
@ -396,18 +396,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
movability: _,
|
||||
fake_reads: _,
|
||||
}) => {
|
||||
let closure_def = if let Some((did, const_param_id)) =
|
||||
ty::WithOptConstParam::try_lookup(closure_id, self.tcx)
|
||||
{
|
||||
ty::WithOptConstParam { did, const_param_did: Some(const_param_id) }
|
||||
} else {
|
||||
ty::WithOptConstParam::unknown(closure_id)
|
||||
};
|
||||
self.visit_inner_body(closure_def);
|
||||
self.visit_inner_body(closure_id);
|
||||
}
|
||||
ExprKind::ConstBlock { did, substs: _ } => {
|
||||
let def_id = did.expect_local();
|
||||
self.visit_inner_body(ty::WithOptConstParam::unknown(def_id));
|
||||
self.visit_inner_body(def_id);
|
||||
}
|
||||
ExprKind::Field { lhs, .. } => {
|
||||
let lhs = &self.thir[lhs];
|
||||
@ -706,14 +699,14 @@ impl UnsafeOpKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
|
||||
pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
|
||||
// THIR unsafeck is gated under `-Z thir-unsafeck`
|
||||
if !tcx.sess.opts.unstable_opts.thir_unsafeck {
|
||||
return;
|
||||
}
|
||||
|
||||
// Closures and inline consts are handled by their owner, if it has a body
|
||||
if tcx.is_typeck_child(def.did.to_def_id()) {
|
||||
if tcx.is_typeck_child(def.to_def_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -726,7 +719,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
|
||||
return;
|
||||
}
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||
let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
|
||||
if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
|
||||
BodyUnsafety::Unsafe(fn_sig.span)
|
||||
@ -734,7 +727,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
|
||||
BodyUnsafety::Safe
|
||||
}
|
||||
});
|
||||
let body_target_features = &tcx.body_codegen_attrs(def.did.to_def_id()).target_features;
|
||||
let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
|
||||
let safety_context =
|
||||
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
|
||||
let mut visitor = UnsafetyVisitor {
|
||||
@ -746,23 +739,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
|
||||
body_target_features,
|
||||
assignment_info: None,
|
||||
in_union_destructure: false,
|
||||
param_env: tcx.param_env(def.did),
|
||||
param_env: tcx.param_env(def),
|
||||
inside_adt: false,
|
||||
};
|
||||
visitor.visit_expr(&thir[expr]);
|
||||
}
|
||||
|
||||
pub(crate) fn thir_check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.thir_check_unsafety_for_const_arg(def)
|
||||
} else {
|
||||
check_unsafety(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn thir_check_unsafety_for_const_arg(
|
||||
tcx: TyCtxt<'_>,
|
||||
(did, param_did): (LocalDefId, DefId),
|
||||
) {
|
||||
check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ pub fn provide(providers: &mut Providers) {
|
||||
providers.lit_to_mir_constant = build::lit_to_mir_constant;
|
||||
providers.mir_built = build::mir_built;
|
||||
providers.thir_check_unsafety = check_unsafety::thir_check_unsafety;
|
||||
providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg;
|
||||
providers.thir_body = thir::cx::thir_body;
|
||||
providers.thir_tree = thir::print::thir_tree;
|
||||
providers.thir_flat = thir::print::thir_flat;
|
||||
|
@ -20,25 +20,25 @@ use rustc_span::Span;
|
||||
|
||||
pub(crate) fn thir_body(
|
||||
tcx: TyCtxt<'_>,
|
||||
owner_def: ty::WithOptConstParam<LocalDefId>,
|
||||
owner_def: LocalDefId,
|
||||
) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
|
||||
let hir = tcx.hir();
|
||||
let body = hir.body(hir.body_owned_by(owner_def.did));
|
||||
let body = hir.body(hir.body_owned_by(owner_def));
|
||||
let mut cx = Cx::new(tcx, owner_def);
|
||||
if let Some(reported) = cx.typeck_results.tainted_by_errors {
|
||||
return Err(reported);
|
||||
}
|
||||
let expr = cx.mirror_expr(&body.value);
|
||||
|
||||
let owner_id = hir.local_def_id_to_hir_id(owner_def.did);
|
||||
let owner_id = hir.local_def_id_to_hir_id(owner_def);
|
||||
if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) {
|
||||
let closure_env_param = cx.closure_env_param(owner_def.did, owner_id);
|
||||
let closure_env_param = cx.closure_env_param(owner_def, owner_id);
|
||||
let explicit_params = cx.explicit_params(owner_id, fn_decl, body);
|
||||
cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect();
|
||||
|
||||
// The resume argument may be missing, in that case we need to provide it here.
|
||||
// It will always be `()` in this case.
|
||||
if tcx.def_kind(owner_def.did) == DefKind::Generator && body.params.is_empty() {
|
||||
if tcx.def_kind(owner_def) == DefKind::Generator && body.params.is_empty() {
|
||||
cx.thir.params.push(Param {
|
||||
ty: tcx.mk_unit(),
|
||||
pat: None,
|
||||
@ -78,13 +78,12 @@ struct Cx<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Cx<'tcx> {
|
||||
fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> {
|
||||
let typeck_results = tcx.typeck_opt_const_arg(def);
|
||||
let did = def.did;
|
||||
fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Cx<'tcx> {
|
||||
let typeck_results = tcx.typeck(def);
|
||||
let hir = tcx.hir();
|
||||
let hir_id = hir.local_def_id_to_hir_id(did);
|
||||
let hir_id = hir.local_def_id_to_hir_id(def);
|
||||
|
||||
let body_type = if hir.body_owner_kind(did).is_fn_or_closure() {
|
||||
let body_type = if hir.body_owner_kind(def).is_fn_or_closure() {
|
||||
// fetch the fully liberated fn signature (that is, all bound
|
||||
// types/lifetimes replaced)
|
||||
BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id])
|
||||
@ -106,11 +105,11 @@ impl<'tcx> Cx<'tcx> {
|
||||
Cx {
|
||||
tcx,
|
||||
thir: Thir::new(body_type),
|
||||
param_env: tcx.param_env(def.did),
|
||||
region_scope_tree: tcx.region_scope_tree(def.did),
|
||||
param_env: tcx.param_env(def),
|
||||
region_scope_tree: tcx.region_scope_tree(def),
|
||||
typeck_results,
|
||||
rvalue_scopes: &typeck_results.rvalue_scopes,
|
||||
body_owner: did.to_def_id(),
|
||||
body_owner: def.to_def_id(),
|
||||
adjustment_span: None,
|
||||
apply_adjustments: hir
|
||||
.attrs(hir_id)
|
||||
|
@ -27,7 +27,7 @@ use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::Span;
|
||||
|
||||
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
let Ok((thir, expr)) = tcx.thir_body(ty::WithOptConstParam::unknown(def_id)) else { return };
|
||||
let Ok((thir, expr)) = tcx.thir_body(def_id) else { return };
|
||||
let thir = thir.borrow();
|
||||
let pattern_arena = TypedArena::default();
|
||||
let mut visitor = MatchVisitor {
|
||||
|
@ -3,7 +3,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
|
||||
pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String {
|
||||
match super::cx::thir_body(tcx, owner_def) {
|
||||
Ok((thir, _)) => {
|
||||
let thir = thir.steal();
|
||||
@ -15,7 +15,7 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalD
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
|
||||
pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String {
|
||||
match super::cx::thir_body(tcx, owner_def) {
|
||||
Ok((thir, _)) => format!("{:#?}", thir.steal()),
|
||||
Err(_) => "error".into(),
|
||||
|
@ -148,7 +148,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
||||
|
||||
if let Some(uv) = maybe_uneval {
|
||||
if uv.promoted.is_none() {
|
||||
let def_id = uv.def.def_id_for_type_of();
|
||||
let def_id = uv.def;
|
||||
if self.tcx.def_kind(def_id) == DefKind::InlineConst {
|
||||
let local_def_id = def_id.expect_local();
|
||||
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
|
||||
@ -375,22 +375,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
|
||||
}
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
unsafety_check_result: |tcx, def_id| {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.unsafety_check_result_for_const_arg(def)
|
||||
} else {
|
||||
unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
},
|
||||
unsafety_check_result_for_const_arg: |tcx, (did, param_did)| {
|
||||
unsafety_check_result(
|
||||
tcx,
|
||||
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
||||
)
|
||||
},
|
||||
..*providers
|
||||
};
|
||||
*providers = Providers { unsafety_check_result, ..*providers };
|
||||
}
|
||||
|
||||
/// Context information for [`UnusedUnsafeVisitor`] traversal,
|
||||
@ -492,10 +477,7 @@ fn check_unused_unsafe(
|
||||
unused_unsafes
|
||||
}
|
||||
|
||||
fn unsafety_check_result(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &UnsafetyCheckResult {
|
||||
fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult {
|
||||
debug!("unsafety_violations({:?})", def);
|
||||
|
||||
// N.B., this borrow is valid because all the consumers of
|
||||
@ -510,13 +492,13 @@ fn unsafety_check_result(
|
||||
});
|
||||
}
|
||||
|
||||
let param_env = tcx.param_env(def.did);
|
||||
let param_env = tcx.param_env(def);
|
||||
|
||||
let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env);
|
||||
let mut checker = UnsafetyChecker::new(body, def, tcx, param_env);
|
||||
checker.visit_body(&body);
|
||||
|
||||
let unused_unsafes = (!tcx.is_typeck_child(def.did.to_def_id()))
|
||||
.then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks));
|
||||
let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id()))
|
||||
.then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks));
|
||||
|
||||
tcx.arena.alloc(UnsafetyCheckResult {
|
||||
violations: checker.violations,
|
||||
|
@ -164,7 +164,6 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool {
|
||||
/// whether that means const mir or runtime mir. For `const fn` this opts for runtime
|
||||
/// mir.
|
||||
fn mir_body(tcx: TyCtxt<'_>, def_id: DefId) -> &mir::Body<'_> {
|
||||
let id = ty::WithOptConstParam::unknown(def_id);
|
||||
let def = ty::InstanceDef::Item(id);
|
||||
let def = ty::InstanceDef::Item(def_id);
|
||||
tcx.instance_mir(def)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
let body = &*tcx.mir_built(ty::WithOptConstParam::unknown(local_def_id)).borrow();
|
||||
let body = &*tcx.mir_built(local_def_id).borrow();
|
||||
|
||||
let body_ty = tcx.type_of(def_id).skip_binder();
|
||||
let body_abi = match body_ty.kind() {
|
||||
|
@ -1399,7 +1399,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
|
||||
) -> GeneratorLayout<'tcx> {
|
||||
assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
|
||||
|
||||
let (body, _) = tcx.mir_promoted(ty::WithOptConstParam::unknown(def_id));
|
||||
let (body, _) = tcx.mir_promoted(def_id);
|
||||
let body = body.borrow();
|
||||
let body = &*body;
|
||||
|
||||
|
@ -148,8 +148,7 @@ pub(crate) fn mir_inliner_callees<'tcx>(
|
||||
let guard;
|
||||
let body = match (instance, instance.def_id().as_local()) {
|
||||
(InstanceDef::Item(_), Some(def_id)) => {
|
||||
let def = ty::WithOptConstParam::unknown(def_id);
|
||||
steal = tcx.mir_promoted(def).0;
|
||||
steal = tcx.mir_promoted(def_id).0;
|
||||
guard = steal.borrow();
|
||||
&*guard
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
@ -111,36 +111,17 @@ pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
mir_keys,
|
||||
mir_const,
|
||||
mir_const_qualif: |tcx, def_id| {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.mir_const_qualif_const_arg(def)
|
||||
} else {
|
||||
mir_const_qualif(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
},
|
||||
mir_const_qualif_const_arg: |tcx, (did, param_did)| {
|
||||
mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
},
|
||||
mir_const_qualif,
|
||||
mir_promoted,
|
||||
mir_drops_elaborated_and_const_checked,
|
||||
mir_for_ctfe,
|
||||
mir_for_ctfe_of_const_arg,
|
||||
mir_generator_witnesses: generator::mir_generator_witnesses,
|
||||
optimized_mir,
|
||||
is_mir_available,
|
||||
is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
|
||||
mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
|
||||
mir_inliner_callees: inline::cycle::mir_inliner_callees,
|
||||
promoted_mir: |tcx, def_id| {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.promoted_mir_of_const_arg(def)
|
||||
} else {
|
||||
promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
},
|
||||
promoted_mir_of_const_arg: |tcx, (did, param_did)| {
|
||||
promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
},
|
||||
promoted_mir,
|
||||
deduced_param_attrs: deduce_param_attrs::deduced_param_attrs,
|
||||
..*providers
|
||||
};
|
||||
@ -234,8 +215,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
|
||||
set
|
||||
}
|
||||
|
||||
fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs {
|
||||
let const_kind = tcx.hir().body_const_context(def.did);
|
||||
fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
||||
let const_kind = tcx.hir().body_const_context(def);
|
||||
|
||||
// No need to const-check a non-const `fn`.
|
||||
if const_kind.is_none() {
|
||||
@ -253,7 +234,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) ->
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def.did) };
|
||||
let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def) };
|
||||
|
||||
let mut validator = check_consts::check::Checker::new(&ccx);
|
||||
validator.check_body();
|
||||
@ -266,22 +247,14 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) ->
|
||||
/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
|
||||
/// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
|
||||
/// We used to have this for pre-miri MIR based const eval.
|
||||
fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal<Body<'_>> {
|
||||
if let Some(def) = def.try_upgrade(tcx) {
|
||||
return tcx.mir_const(def);
|
||||
}
|
||||
|
||||
fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
|
||||
// Unsafety check uses the raw mir, so make sure it is run.
|
||||
if !tcx.sess.opts.unstable_opts.thir_unsafeck {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
tcx.ensure_with_value().unsafety_check_result_for_const_arg((def.did, param_did));
|
||||
} else {
|
||||
tcx.ensure_with_value().unsafety_check_result(def.did);
|
||||
}
|
||||
tcx.ensure_with_value().unsafety_check_result(def);
|
||||
}
|
||||
|
||||
// has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
|
||||
tcx.ensure_with_value().has_ffi_unwind_calls(def.did);
|
||||
tcx.ensure_with_value().has_ffi_unwind_calls(def);
|
||||
|
||||
let mut body = tcx.mir_built(def).steal();
|
||||
|
||||
@ -307,16 +280,12 @@ fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal<
|
||||
/// Compute the main MIR body and the list of MIR bodies of the promoteds.
|
||||
fn mir_promoted(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def: LocalDefId,
|
||||
) -> (&Steal<Body<'_>>, &Steal<IndexVec<Promoted, Body<'_>>>) {
|
||||
if let Some(def) = def.try_upgrade(tcx) {
|
||||
return tcx.mir_promoted(def);
|
||||
}
|
||||
|
||||
// Ensure that we compute the `mir_const_qualif` for constants at
|
||||
// this point, before we steal the mir-const result.
|
||||
// Also this means promotion can rely on all const checks having been done.
|
||||
let const_qualifs = tcx.mir_const_qualif_opt_const_arg(def);
|
||||
let const_qualifs = tcx.mir_const_qualif(def);
|
||||
let mut body = tcx.mir_const(def).steal();
|
||||
if let Some(error_reported) = const_qualifs.tainted_by_errors {
|
||||
body.tainted_by_errors = Some(error_reported);
|
||||
@ -344,38 +313,22 @@ fn mir_promoted(
|
||||
|
||||
/// Compute the MIR that is used during CTFE (and thus has no optimizations run on it)
|
||||
fn mir_for_ctfe(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &Body<'_> {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.mir_for_ctfe_of_const_arg(def)
|
||||
} else {
|
||||
tcx.arena.alloc(inner_mir_for_ctfe(tcx, ty::WithOptConstParam::unknown(def_id)))
|
||||
}
|
||||
tcx.arena.alloc(inner_mir_for_ctfe(tcx, def_id))
|
||||
}
|
||||
|
||||
/// Same as `mir_for_ctfe`, but used to get the MIR of a const generic parameter.
|
||||
/// The docs on `WithOptConstParam` explain this a bit more, but the TLDR is that
|
||||
/// we'd get cycle errors with `mir_for_ctfe`, because typeck would need to typeck
|
||||
/// the const parameter while type checking the main body, which in turn would try
|
||||
/// to type check the main body again.
|
||||
fn mir_for_ctfe_of_const_arg(tcx: TyCtxt<'_>, (did, param_did): (LocalDefId, DefId)) -> &Body<'_> {
|
||||
tcx.arena.alloc(inner_mir_for_ctfe(
|
||||
tcx,
|
||||
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
||||
))
|
||||
}
|
||||
|
||||
fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||
fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
|
||||
// FIXME: don't duplicate this between the optimized_mir/mir_for_ctfe queries
|
||||
if tcx.is_constructor(def.did.to_def_id()) {
|
||||
if tcx.is_constructor(def.to_def_id()) {
|
||||
// There's no reason to run all of the MIR passes on constructors when
|
||||
// we can just output the MIR we want directly. This also saves const
|
||||
// qualification and borrow checking the trouble of special casing
|
||||
// constructors.
|
||||
return shim::build_adt_ctor(tcx, def.did.to_def_id());
|
||||
return shim::build_adt_ctor(tcx, def.to_def_id());
|
||||
}
|
||||
|
||||
let context = tcx
|
||||
.hir()
|
||||
.body_const_context(def.did)
|
||||
.body_const_context(def)
|
||||
.expect("mir_for_ctfe should not be used for runtime functions");
|
||||
|
||||
let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
|
||||
@ -413,29 +366,19 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
|
||||
/// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
|
||||
/// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
|
||||
/// end up missing the source MIR due to stealing happening.
|
||||
fn mir_drops_elaborated_and_const_checked(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &Steal<Body<'_>> {
|
||||
if let Some(def) = def.try_upgrade(tcx) {
|
||||
return tcx.mir_drops_elaborated_and_const_checked(def);
|
||||
}
|
||||
|
||||
fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
|
||||
if tcx.sess.opts.unstable_opts.drop_tracking_mir
|
||||
&& let DefKind::Generator = tcx.def_kind(def.did)
|
||||
&& let DefKind::Generator = tcx.def_kind(def)
|
||||
{
|
||||
tcx.ensure_with_value().mir_generator_witnesses(def.did);
|
||||
tcx.ensure_with_value().mir_generator_witnesses(def);
|
||||
}
|
||||
let mir_borrowck = tcx.mir_borrowck_opt_const_arg(def);
|
||||
let mir_borrowck = tcx.mir_borrowck(def);
|
||||
|
||||
let is_fn_like = tcx.def_kind(def.did).is_fn_like();
|
||||
let is_fn_like = tcx.def_kind(def).is_fn_like();
|
||||
if is_fn_like {
|
||||
let did = def.did.to_def_id();
|
||||
let def = ty::WithOptConstParam::unknown(did);
|
||||
|
||||
// Do not compute the mir call graph without said call graph actually being used.
|
||||
if inline::Inline.is_enabled(&tcx.sess) {
|
||||
tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def));
|
||||
tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,7 +531,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
||||
/// Optimize the MIR and prepare it for codegen.
|
||||
fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> {
|
||||
assert_eq!(ty::WithOptConstParam::try_lookup(did, tcx), None);
|
||||
tcx.arena.alloc(inner_optimized_mir(tcx, did))
|
||||
}
|
||||
|
||||
@ -610,8 +552,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
|
||||
Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other),
|
||||
}
|
||||
debug!("about to call mir_drops_elaborated...");
|
||||
let body =
|
||||
tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal();
|
||||
let body = tcx.mir_drops_elaborated_and_const_checked(did).steal();
|
||||
let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst);
|
||||
debug!("body: {:#?}", body);
|
||||
run_optimization_passes(tcx, &mut body);
|
||||
@ -621,15 +562,12 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
|
||||
|
||||
/// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for
|
||||
/// constant evaluation once all substitutions become known.
|
||||
fn promoted_mir(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &IndexVec<Promoted, Body<'_>> {
|
||||
if tcx.is_constructor(def.did.to_def_id()) {
|
||||
fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_>> {
|
||||
if tcx.is_constructor(def.to_def_id()) {
|
||||
return tcx.arena.alloc(IndexVec::new());
|
||||
}
|
||||
|
||||
let tainted_by_errors = tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors;
|
||||
let tainted_by_errors = tcx.mir_borrowck(def).tainted_by_errors;
|
||||
let mut promoted = tcx.mir_promoted(def).1.steal();
|
||||
|
||||
for body in &mut promoted {
|
||||
|
@ -267,7 +267,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
|
||||
match mono_item {
|
||||
MonoItem::Fn(instance) => {
|
||||
let def_id = match instance.def {
|
||||
ty::InstanceDef::Item(def) => def.did,
|
||||
ty::InstanceDef::Item(def) => def,
|
||||
ty::InstanceDef::VTableShim(..)
|
||||
| ty::InstanceDef::ReifyShim(..)
|
||||
| ty::InstanceDef::FnPtrShim(..)
|
||||
@ -421,8 +421,7 @@ fn mono_item_visibility<'tcx>(
|
||||
};
|
||||
|
||||
let def_id = match instance.def {
|
||||
InstanceDef::Item(def) => def.did,
|
||||
InstanceDef::DropGlue(def_id, Some(_)) => def_id,
|
||||
InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id,
|
||||
|
||||
// We match the visibility of statics here
|
||||
InstanceDef::ThreadLocalShim(def_id) => {
|
||||
|
@ -232,7 +232,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
|
||||
/// a closure, generator or constant).
|
||||
#[instrument(level = "debug", skip(self, def_id, substs))]
|
||||
fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) {
|
||||
let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id));
|
||||
let instance = ty::InstanceDef::Item(def_id);
|
||||
let unused = self.tcx.unused_generic_params(instance);
|
||||
debug!(?self.unused_parameters, ?unused);
|
||||
for (i, arg) in substs.iter().enumerate() {
|
||||
@ -272,10 +272,10 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
|
||||
// Avoid considering `T` unused when constants are of the form:
|
||||
// `<Self as Foo<T>>::foo::promoted[p]`
|
||||
if let Some(p) = promoted {
|
||||
if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self {
|
||||
if self.def_id == def && !self.tcx.generics_of(def).has_self {
|
||||
// If there is a promoted, don't look at the substs - since it will always contain
|
||||
// the generic parameters, instead, traverse the promoted MIR.
|
||||
let promoted = self.tcx.promoted_mir(def.did);
|
||||
let promoted = self.tcx.promoted_mir(def);
|
||||
self.visit_body(&promoted[p]);
|
||||
}
|
||||
}
|
||||
@ -305,9 +305,9 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs })
|
||||
if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) =>
|
||||
if matches!(self.tcx.def_kind(def), DefKind::AnonConst) =>
|
||||
{
|
||||
self.visit_child_body(def.did, substs);
|
||||
self.visit_child_body(def, substs);
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
_ => c.super_visit_with(self),
|
||||
|
@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::profiling::SelfProfiler;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_middle::ty::{TyCtxt, WithOptConstParam};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_query_system::query::QueryCache;
|
||||
use std::fmt::Debug;
|
||||
use std::io::Write;
|
||||
@ -151,37 +151,6 @@ impl SpecIntoSelfProfilingString for LocalDefId {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SpecIntoSelfProfilingString> SpecIntoSelfProfilingString for WithOptConstParam<T> {
|
||||
fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId {
|
||||
// We print `WithOptConstParam` values as tuples to make them shorter
|
||||
// and more readable, without losing information:
|
||||
//
|
||||
// "WithOptConstParam { did: foo::bar, const_param_did: Some(foo::baz) }"
|
||||
// becomes "(foo::bar, foo::baz)" and
|
||||
// "WithOptConstParam { did: foo::bar, const_param_did: None }"
|
||||
// becomes "(foo::bar, _)".
|
||||
|
||||
let did = StringComponent::Ref(self.did.to_self_profile_string(builder));
|
||||
|
||||
let const_param_did = if let Some(const_param_did) = self.const_param_did {
|
||||
let const_param_did = builder.def_id_to_string_id(const_param_did);
|
||||
StringComponent::Ref(const_param_did)
|
||||
} else {
|
||||
StringComponent::Value("_")
|
||||
};
|
||||
|
||||
let components = [
|
||||
StringComponent::Value("("),
|
||||
did,
|
||||
StringComponent::Value(", "),
|
||||
const_param_did,
|
||||
StringComponent::Value(")"),
|
||||
];
|
||||
|
||||
builder.profiler.alloc_string(&components[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1)
|
||||
where
|
||||
T0: SpecIntoSelfProfilingString,
|
||||
|
@ -198,7 +198,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
|
||||
let identity_substs =
|
||||
ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id);
|
||||
let did = ty::WithOptConstParam::unknown(assoc_def.item.def_id);
|
||||
let did = assoc_def.item.def_id;
|
||||
let kind =
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
|
||||
ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
|
||||
|
@ -796,10 +796,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())),
|
||||
Ok(None) => {
|
||||
let tcx = self.tcx;
|
||||
let def_id = unevaluated.def.did;
|
||||
let reported =
|
||||
tcx.sess.emit_err(UnableToConstructConstantValue {
|
||||
span: tcx.def_span(def_id),
|
||||
span: tcx.def_span(unevaluated.def),
|
||||
unevaluated: unevaluated,
|
||||
});
|
||||
Err(ErrorHandled::Reported(reported))
|
||||
|
@ -44,7 +44,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
let ct = tcx.expand_abstract_consts(unexpanded_ct);
|
||||
|
||||
let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
|
||||
tcx.def_kind(uv.def.did) == DefKind::AnonConst
|
||||
tcx.def_kind(uv.def) == DefKind::AnonConst
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@ -119,7 +119,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
tcx.sess
|
||||
.struct_span_fatal(
|
||||
// Slightly better span than just using `span` alone
|
||||
if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def.did) } else { span },
|
||||
if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span },
|
||||
"failed to evaluate generic const expression",
|
||||
)
|
||||
.note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`")
|
||||
|
@ -1476,7 +1476,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
};
|
||||
let mut err =
|
||||
self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
|
||||
let const_span = self.tcx.def_span(uv.def.did);
|
||||
let const_span = self.tcx.def_span(uv.def);
|
||||
match self.tcx.sess.source_map().span_to_snippet(const_span) {
|
||||
Ok(snippet) => err.help(&format!(
|
||||
"try adding a `where` bound using this expression: `where [(); {}]:`",
|
||||
@ -1771,7 +1771,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
.tcx
|
||||
.mk_const(
|
||||
ty::UnevaluatedConst {
|
||||
def: ty::WithOptConstParam::unknown(data.projection_ty.def_id),
|
||||
def: data.projection_ty.def_id,
|
||||
substs: data.projection_ty.substs,
|
||||
},
|
||||
ct.ty(),
|
||||
|
@ -540,8 +540,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
use ty::ConstKind::Unevaluated;
|
||||
match (c1.kind(), c2.kind()) {
|
||||
(Unevaluated(a), Unevaluated(b))
|
||||
if a.def.did == b.def.did
|
||||
&& tcx.def_kind(a.def.did) == DefKind::AssocConst =>
|
||||
if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst =>
|
||||
{
|
||||
if let Ok(new_obligations) = infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
|
@ -2131,9 +2131,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||
let ty = tcx.type_of(assoc_ty.item.def_id);
|
||||
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
|
||||
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
|
||||
let identity_substs =
|
||||
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
|
||||
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
|
||||
let did = assoc_ty.item.def_id;
|
||||
let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, did);
|
||||
let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
|
||||
ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
|
||||
} else {
|
||||
|
@ -896,8 +896,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
use ty::ConstKind::Unevaluated;
|
||||
match (c1.kind(), c2.kind()) {
|
||||
(Unevaluated(a), Unevaluated(b))
|
||||
if a.def.did == b.def.did
|
||||
&& tcx.def_kind(a.def.did) == DefKind::AssocConst =>
|
||||
if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst =>
|
||||
{
|
||||
if let Ok(InferOk { obligations, value: () }) = self
|
||||
.infcx
|
||||
|
@ -478,7 +478,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
if !ct.has_escaping_bound_vars() {
|
||||
let obligations = self.nominal_obligations(uv.def.did, uv.substs);
|
||||
let obligations = self.nominal_obligations(uv.def, uv.substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
let predicate =
|
||||
|
@ -132,7 +132,7 @@ fn recurse_build<'tcx>(
|
||||
tcx.mk_const(val, node.ty)
|
||||
}
|
||||
&ExprKind::NamedConst { def_id, substs, user_ty: _ } => {
|
||||
let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||
let uneval = ty::UnevaluatedConst::new(def_id, substs);
|
||||
tcx.mk_const(uneval, node.ty)
|
||||
}
|
||||
ExprKind::ConstParam { param, .. } => tcx.mk_const(*param, node.ty),
|
||||
@ -391,52 +391,36 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> {
|
||||
/// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead.
|
||||
pub fn thir_abstract_const(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
def: LocalDefId,
|
||||
) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> {
|
||||
if tcx.features().generic_const_exprs {
|
||||
match tcx.def_kind(def.did) {
|
||||
// FIXME(generic_const_exprs): We currently only do this for anonymous constants,
|
||||
// meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether
|
||||
// we want to look into them or treat them as opaque projections.
|
||||
//
|
||||
// Right now we do neither of that and simply always fail to unify them.
|
||||
DefKind::AnonConst | DefKind::InlineConst => (),
|
||||
_ => return Ok(None),
|
||||
}
|
||||
|
||||
let body = tcx.thir_body(def)?;
|
||||
let (body, body_id) = (&*body.0.borrow(), body.1);
|
||||
|
||||
let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
|
||||
visit::walk_expr(&mut is_poly_vis, &body[body_id]);
|
||||
if !is_poly_vis.is_poly {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let root_span = body.exprs[body_id].span;
|
||||
|
||||
Some(recurse_build(tcx, body, body_id, root_span)).transpose()
|
||||
} else {
|
||||
Ok(None)
|
||||
if !tcx.features().generic_const_exprs {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
match tcx.def_kind(def) {
|
||||
// FIXME(generic_const_exprs): We currently only do this for anonymous constants,
|
||||
// meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether
|
||||
// we want to look into them or treat them as opaque projections.
|
||||
//
|
||||
// Right now we do neither of that and simply always fail to unify them.
|
||||
DefKind::AnonConst | DefKind::InlineConst => (),
|
||||
_ => return Ok(None),
|
||||
}
|
||||
|
||||
let body = tcx.thir_body(def)?;
|
||||
let (body, body_id) = (&*body.0.borrow(), body.1);
|
||||
|
||||
let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
|
||||
visit::walk_expr(&mut is_poly_vis, &body[body_id]);
|
||||
if !is_poly_vis.is_poly {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let root_span = body.exprs[body_id].span;
|
||||
|
||||
Some(recurse_build(tcx, body, body_id, root_span)).transpose()
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers {
|
||||
destructure_const,
|
||||
thir_abstract_const: |tcx, def_id| {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.thir_abstract_const_of_const_arg(def)
|
||||
} else {
|
||||
thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
},
|
||||
thir_abstract_const_of_const_arg: |tcx, (did, param_did)| {
|
||||
thir_abstract_const(
|
||||
tcx,
|
||||
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
||||
)
|
||||
},
|
||||
..*providers
|
||||
};
|
||||
*providers = ty::query::Providers { destructure_const, thir_abstract_const, ..*providers };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::traits::CodegenObligationError;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
@ -13,49 +13,27 @@ use crate::errors::UnexpectedFnPtrAssociatedItem;
|
||||
fn resolve_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
let (param_env, (did, substs)) = key.into_parts();
|
||||
inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs)))
|
||||
}
|
||||
|
||||
fn resolve_instance_of_const_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
let (param_env, (did, const_param_did, substs)) = key.into_parts();
|
||||
inner_resolve_instance(
|
||||
tcx,
|
||||
param_env.and((
|
||||
ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) },
|
||||
substs,
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
fn inner_resolve_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
let (param_env, (def, substs)) = key.into_parts();
|
||||
|
||||
let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) {
|
||||
let result = if let Some(trait_def_id) = tcx.trait_of_item(def) {
|
||||
debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
|
||||
resolve_associated_item(
|
||||
tcx,
|
||||
def.did,
|
||||
def,
|
||||
param_env,
|
||||
trait_def_id,
|
||||
tcx.normalize_erasing_regions(param_env, substs),
|
||||
)
|
||||
} else {
|
||||
let ty = tcx.type_of(def.def_id_for_type_of());
|
||||
let ty = tcx.type_of(def);
|
||||
let item_type =
|
||||
tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder());
|
||||
|
||||
let def = match *item_type.kind() {
|
||||
ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
|
||||
debug!(" => intrinsic");
|
||||
ty::InstanceDef::Intrinsic(def.did)
|
||||
ty::InstanceDef::Intrinsic(def)
|
||||
}
|
||||
ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
|
||||
let ty = substs.type_at(0);
|
||||
@ -200,15 +178,11 @@ fn resolve_associated_item<'tcx>(
|
||||
Some(ty::Instance::new(leaf_def.item.def_id, substs))
|
||||
}
|
||||
traits::ImplSource::Generator(generator_data) => Some(Instance {
|
||||
def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
|
||||
generator_data.generator_def_id,
|
||||
)),
|
||||
def: ty::InstanceDef::Item(generator_data.generator_def_id),
|
||||
substs: generator_data.substs,
|
||||
}),
|
||||
traits::ImplSource::Future(future_data) => Some(Instance {
|
||||
def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
|
||||
future_data.generator_def_id,
|
||||
)),
|
||||
def: ty::InstanceDef::Item(future_data.generator_def_id),
|
||||
substs: future_data.substs,
|
||||
}),
|
||||
traits::ImplSource::Closure(closure_data) => {
|
||||
@ -292,6 +266,5 @@ fn resolve_associated_item<'tcx>(
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers =
|
||||
ty::query::Providers { resolve_instance, resolve_instance_of_const_arg, ..*providers };
|
||||
*providers = ty::query::Providers { resolve_instance, ..*providers };
|
||||
}
|
||||
|
@ -243,9 +243,9 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
|
||||
match n.kind() {
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs: _ }) => {
|
||||
let s = if let Some(def) = def.as_local() {
|
||||
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did))
|
||||
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def))
|
||||
} else {
|
||||
inline::print_inlined_const(cx.tcx, def.did)
|
||||
inline::print_inlined_const(cx.tcx, def)
|
||||
};
|
||||
|
||||
s
|
||||
|
@ -196,11 +196,9 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<
|
||||
fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
|
||||
let substs = cx.typeck_results().node_substs(hir_id);
|
||||
|
||||
let result = cx.tcx.const_eval_resolve(
|
||||
cx.param_env,
|
||||
mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs),
|
||||
None,
|
||||
);
|
||||
let result = cx
|
||||
.tcx
|
||||
.const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None);
|
||||
is_value_unfrozen_raw(cx, result, ty)
|
||||
}
|
||||
|
||||
|
@ -450,11 +450,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
|
||||
let result = self
|
||||
.lcx
|
||||
.tcx
|
||||
.const_eval_resolve(
|
||||
self.param_env,
|
||||
mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs),
|
||||
None,
|
||||
)
|
||||
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None)
|
||||
.ok()
|
||||
.map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?;
|
||||
let result = miri_to_const(self.lcx.tcx, result);
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:8 ~ storage_live[HASH]::multiple_storage), const_param_did: None }) (before pass CheckPackedRef) at bb0[1]:
|
||||
error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (before pass CheckPackedRef) at bb0[1]:
|
||||
StorageLive(_1) which already has storage here
|
||||
--> $DIR/storage-live.rs:22:13
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user