ty: add ty::ConstKind::Error
to replace tcx.consts.err
.
This commit is contained in:
parent
4e4d49d60f
commit
2deb39dd1f
@ -251,7 +251,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
bug!("unexpected const {:?}", ct)
|
||||
}
|
||||
|
||||
ty::ConstKind::Param(_) | ty::ConstKind::Value(_) | ty::ConstKind::Unevaluated(..) => {}
|
||||
ty::ConstKind::Param(_)
|
||||
| ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Unevaluated(..)
|
||||
| ty::ConstKind::Error => {}
|
||||
}
|
||||
|
||||
ct.super_fold_with(self)
|
||||
|
@ -227,7 +227,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
match c.val {
|
||||
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedConst(vid));
|
||||
return self.tcx().consts.err;
|
||||
return self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: c.ty });
|
||||
}
|
||||
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
|
||||
bug!("Unexpected const in full const resolver: {:?}", c);
|
||||
|
@ -182,7 +182,7 @@ pub struct CommonLifetimes<'tcx> {
|
||||
}
|
||||
|
||||
pub struct CommonConsts<'tcx> {
|
||||
pub err: &'tcx Const<'tcx>,
|
||||
pub unit: &'tcx Const<'tcx>,
|
||||
}
|
||||
|
||||
pub struct LocalTableInContext<'a, V> {
|
||||
@ -858,9 +858,9 @@ impl<'tcx> CommonConsts<'tcx> {
|
||||
let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0;
|
||||
|
||||
CommonConsts {
|
||||
err: mk_const(ty::Const {
|
||||
unit: mk_const(ty::Const {
|
||||
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
|
||||
ty: types.err,
|
||||
ty: types.unit,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -70,14 +70,7 @@ impl FlagComputation {
|
||||
| &ty::Str
|
||||
| &ty::Foreign(..) => {}
|
||||
|
||||
// You might think that we could just return Error for
|
||||
// any type containing Error as a component, and get
|
||||
// rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
|
||||
// the exception of function types that return bot).
|
||||
// But doing so caused sporadic memory corruption, and
|
||||
// neither I (tjc) nor nmatsakis could figure out why,
|
||||
// so we're doing it this way.
|
||||
&ty::Error => self.add_flags(TypeFlags::HAS_TY_ERR),
|
||||
&ty::Error => self.add_flags(TypeFlags::HAS_ERROR),
|
||||
|
||||
&ty::Param(_) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_PARAM);
|
||||
@ -239,6 +232,7 @@ impl FlagComputation {
|
||||
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
|
||||
}
|
||||
ty::ConstKind::Value(_) => {}
|
||||
ty::ConstKind::Error => self.add_flags(TypeFlags::HAS_ERROR),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
|
||||
}
|
||||
fn references_error(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_ERR)
|
||||
self.has_type_flags(TypeFlags::HAS_ERROR)
|
||||
}
|
||||
fn has_param_types_or_consts(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
|
||||
|
@ -567,8 +567,8 @@ bitflags! {
|
||||
| TypeFlags::HAS_TY_OPAQUE.bits
|
||||
| TypeFlags::HAS_CT_PROJECTION.bits;
|
||||
|
||||
/// Is an error type reachable?
|
||||
const HAS_TY_ERR = 1 << 13;
|
||||
/// Is an error type/const reachable?
|
||||
const HAS_ERROR = 1 << 13;
|
||||
|
||||
/// Does this have any region that "appears free" in the type?
|
||||
/// Basically anything but [ReLateBound] and [ReErased].
|
||||
|
@ -938,6 +938,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
self.pretty_print_bound_var(debruijn, bound_var)?
|
||||
}
|
||||
ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
|
||||
ty::ConstKind::Error => p!(write("[const error]")),
|
||||
};
|
||||
Ok(self)
|
||||
}
|
||||
|
@ -510,12 +510,21 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
|
||||
let tcx = relation.tcx();
|
||||
|
||||
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
|
||||
// FIXME(eddyb) this doesn't account for lifetime inference variables
|
||||
// being erased by `eval`, *nor* for the polymorphic aspect of `eval`.
|
||||
// That is, we could always use `eval` and it will just return the
|
||||
// old value back if it doesn't succeed.
|
||||
if !x.val.needs_infer() {
|
||||
return x.eval(tcx, relation.param_env()).val;
|
||||
}
|
||||
x.val
|
||||
};
|
||||
|
||||
// FIXME(eddyb) doesn't look like everything below checks that `a.ty == b.ty`.
|
||||
// We could probably always assert it early, as `const` generic parameters
|
||||
// are not allowed to depend on other generic parameters, i.e. are concrete.
|
||||
// (although there could be normalization differences)
|
||||
|
||||
// Currently, the values that can be unified are primitive types,
|
||||
// and those that derive both `PartialEq` and `Eq`, corresponding
|
||||
// to structural-match types.
|
||||
@ -524,6 +533,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
|
||||
// The caller should handle these cases!
|
||||
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
|
||||
}
|
||||
|
||||
(ty::ConstKind::Error, _) | (_, ty::ConstKind::Error) => Ok(ty::ConstKind::Error),
|
||||
|
||||
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
|
||||
return Ok(a);
|
||||
}
|
||||
|
@ -1022,9 +1022,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||
ty::ConstKind::Unevaluated(did, substs, promoted) => {
|
||||
ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted)
|
||||
}
|
||||
ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => {
|
||||
*self
|
||||
}
|
||||
ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Bound(..)
|
||||
| ty::ConstKind::Placeholder(..)
|
||||
| ty::ConstKind::Error => *self,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1033,9 +1034,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||
ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
|
||||
ty::ConstKind::Param(p) => p.visit_with(visitor),
|
||||
ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor),
|
||||
ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
|
||||
false
|
||||
}
|
||||
ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Bound(..)
|
||||
| ty::ConstKind::Placeholder(_)
|
||||
| ty::ConstKind::Error => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2429,6 +2429,10 @@ pub enum ConstKind<'tcx> {
|
||||
|
||||
/// Used to hold computed value.
|
||||
Value(ConstValue<'tcx>),
|
||||
|
||||
/// A placeholder for a const which could not be computed; this is
|
||||
/// propagated to avoid useless error messages.
|
||||
Error,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -170,7 +170,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||
| ty::ConstKind::Param(_)
|
||||
| ty::ConstKind::Placeholder(_)
|
||||
| ty::ConstKind::Bound(..)
|
||||
| ty::ConstKind::Value(_) => {}
|
||||
| ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Error => {}
|
||||
|
||||
ty::ConstKind::Unevaluated(_, substs, _) => {
|
||||
stack.extend(substs.iter().copied().rev());
|
||||
|
@ -518,6 +518,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// Early-return cases.
|
||||
let val_val = match val.val {
|
||||
ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
|
||||
ty::ConstKind::Error => throw_inval!(TypeckError),
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
|
||||
|
@ -972,7 +972,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
)
|
||||
.emit();
|
||||
|
||||
self.tcx().consts.err
|
||||
self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -826,14 +826,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Const => {
|
||||
let ty = tcx.at(span).type_of(param.def_id);
|
||||
// FIXME(const_generics:defaults)
|
||||
if infer_args {
|
||||
// No const parameters were provided, we can infer all.
|
||||
let ty = tcx.at(span).type_of(param.def_id);
|
||||
self.ct_infer(ty, Some(param), span).into()
|
||||
} else {
|
||||
// We've already errored above about the mismatch.
|
||||
tcx.consts.err.into()
|
||||
tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty }).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||
// FIXME: we'd like to use `self.report_error`, but it doesn't yet
|
||||
// accept a &'tcx ty::Const.
|
||||
self.replaced_with_error = true;
|
||||
self.tcx().consts.err
|
||||
self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,13 +316,13 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||
|
||||
fn ct_infer(
|
||||
&self,
|
||||
_: Ty<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
_: Option<&ty::GenericParamDef>,
|
||||
span: Span,
|
||||
) -> &'tcx Const<'tcx> {
|
||||
bad_placeholder_type(self.tcx(), vec![span]).emit();
|
||||
|
||||
self.tcx().consts.err
|
||||
self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty })
|
||||
}
|
||||
|
||||
fn projected_ty_from_poly_trait_ref(
|
||||
@ -2037,7 +2037,8 @@ fn associated_item_predicates(
|
||||
}
|
||||
ty::GenericParamDefKind::Const => {
|
||||
unimplemented_error("const");
|
||||
tcx.consts.err.into()
|
||||
tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: tcx.type_of(param.def_id) })
|
||||
.into()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user