1
Fork 0

Add Ty to mir::Const::Ty

This commit is contained in:
Boxy 2024-06-03 04:46:24 +01:00
parent 8d6705cdb8
commit 60a5bebbe5
19 changed files with 81 additions and 51 deletions

View file

@ -7,7 +7,7 @@ use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput,
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::{
self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex,
self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex,
};
use rustc_middle::{bug, span_bug};
use rustc_target::abi::Size;
@ -50,7 +50,9 @@ pub(crate) fn as_constant_inner<'tcx>(
let const_ = match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg })
{
Ok(c) => c,
Err(LitToConstError::Reported(guar)) => Const::Ty(ty::Const::new_error(tcx, guar)),
Err(LitToConstError::Reported(guar)) => {
Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar))
}
Err(LitToConstError::TypeError) => {
bug!("encountered type error in `lit_to_mir_constant`")
}
@ -82,7 +84,7 @@ pub(crate) fn as_constant_inner<'tcx>(
}
ExprKind::ConstParam { param, def_id: _ } => {
let const_param = ty::Const::new_param(tcx, param);
let const_ = Const::Ty(const_param);
let const_ = Const::Ty(expr.ty, const_param);
ConstOperand { user_ty: None, span, const_ }
}

View file

@ -101,9 +101,9 @@ impl<'tcx> ConstToPat<'tcx> {
// level of indirection can be eliminated
let have_valtree =
matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_, _)));
matches!(cv, mir::Const::Ty(_, c) if matches!(c.kind(), ty::ConstKind::Value(_, _)));
let inlined_const_as_pat = match cv {
mir::Const::Ty(c) => match c.kind() {
mir::Const::Ty(_, c) => match c.kind() {
ty::ConstKind::Param(_)
| ty::ConstKind::Infer(_)
| ty::ConstKind::Bound(_, _)
@ -336,9 +336,9 @@ impl<'tcx> ConstToPat<'tcx> {
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
// `&str` is represented as a valtree, let's keep using this
// optimization for now.
ty::Str => {
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
}
ty::Str => PatKind::Constant {
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
},
// All other references are converted into deref patterns and then recursively
// convert the dereferenced constant to a pattern that is the sub-pattern of the
// deref pattern.
@ -382,13 +382,15 @@ impl<'tcx> ConstToPat<'tcx> {
self.saw_const_match_error.set(Some(e));
return Err(FallbackToOpaqueConst);
} else {
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
PatKind::Constant {
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
}
}
}
ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
// The raw pointers we see here have been "vetted" by valtree construction to be
// just integers, so we simply allow them.
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) }
}
ty::FnPtr(..) => {
unreachable!(

View file

@ -580,7 +580,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.tcx
.const_eval_global_id_for_typeck(param_env_reveal_all, cid, span)
.map(|val| match val {
Some(valtree) => mir::Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)),
Some(valtree) => mir::Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)),
None => mir::Const::Val(
self.tcx
.const_eval_global_id(param_env_reveal_all, cid, span)
@ -659,7 +659,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
};
if let Some(lit_input) = lit_input {
match tcx.at(expr.span).lit_to_const(lit_input) {
Ok(c) => return self.const_to_pat(Const::Ty(c), id, span).kind,
Ok(c) => return self.const_to_pat(Const::Ty(ty, c), id, span).kind,
// If an error occurred, ignore that it's a literal
// and leave reporting the error up to const eval of
// the unevaluated constant below.
@ -681,8 +681,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// but something more principled, like a trait query checking whether this can be turned into a valtree.
if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span)
{
let subpattern =
self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span);
let subpattern = self.const_to_pat(
Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)),
id,
span,
);
PatKind::InlineConstant { subpattern, def: def_id }
} else {
// If that fails, convert it to an opaque constant pattern.
@ -720,10 +723,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
};
let lit_input =
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
let ct_ty = self.typeck_results.expr_ty(expr);
let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
match self.tcx.at(expr.span).lit_to_const(lit_input) {
Ok(constant) => self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span).kind,
Ok(constant) => {
self.const_to_pat(Const::Ty(ct_ty, constant), expr.hir_id, lit.span).kind
}
Err(LitToConstError::Reported(e)) => PatKind::Error(e),
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
}