Remove WithOptconstParam.

This commit is contained in:
Camille GILLOT 2022-05-08 15:53:19 +02:00
parent 0e017fc94a
commit b275d2c30b
68 changed files with 335 additions and 960 deletions

View File

@ -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()

View File

@ -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)

View File

@ -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));

View File

@ -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);

View File

@ -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 =

View File

@ -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]))
}

View File

@ -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");
}

View File

@ -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 {

View File

@ -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.

View File

@ -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)

View File

@ -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),

View File

@ -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)?,

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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 {

View File

@ -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
}

View File

@ -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 {

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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);
}
}
});

View File

@ -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);
}

View File

@ -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 {

View File

@ -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,
)

View File

@ -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() }
}
}

View File

@ -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(..)

View File

@ -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,
)

View File

@ -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)
}
}
}

View File

@ -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)
}
}

View File

@ -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 }
}

View File

@ -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

View File

@ -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)))
}

View File

@ -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,
),

View File

@ -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)

View File

@ -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))
}

View File

@ -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 {

View File

@ -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(..)

View File

@ -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),

View File

@ -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 }

View File

@ -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()

View File

@ -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) })
}

View File

@ -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;

View File

@ -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)

View File

@ -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 {

View File

@ -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(),

View File

@ -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,

View File

@ -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)
}

View File

@ -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() {

View File

@ -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;

View File

@ -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
}

View File

@ -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 {

View File

@ -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) => {

View File

@ -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),

View File

@ -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,

View File

@ -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())

View File

@ -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))

View File

@ -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)]`")

View File

@ -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(),

View File

@ -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)

View File

@ -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 {

View File

@ -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

View File

@ -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 =

View File

@ -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 };
}

View File

@ -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 };
}

View File

@ -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

View File

@ -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)
}

View File

@ -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);

View File

@ -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
|