Skip to content

Commit

Permalink
compare consts using ptr equality
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed May 27, 2020
1 parent 783139b commit ef5aa6a
Show file tree
Hide file tree
Showing 26 changed files with 114 additions and 71 deletions.
6 changes: 2 additions & 4 deletions src/librustc_infer/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,10 +658,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
self.fold_const(bound_to)
} else {
let var = self.canonical_var(info, const_var.into());
self.tcx().mk_const(ty::Const {
val: ty::ConstKind::Bound(self.binder_index, var),
ty: self.fold_ty(const_var.ty),
})
self.tcx()
.mk_const(self.fold_ty(const_var.ty), ty::ConstKind::Bound(self.binder_index, var))
}
}
}
8 changes: 4 additions & 4 deletions src/librustc_infer/infer/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name };
self.tcx
.mk_const(ty::Const {
val: ty::ConstKind::Placeholder(placeholder_mapped),
ty: self.tcx.types.err, // FIXME(const_generics)
})
.mk_const(
self.tcx.types.err, // FIXME(const_generics)
ty::ConstKind::Placeholder(placeholder_mapped),
)
.into()
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_infer/infer/fudge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.val {
if self.const_vars.0.contains(&vid) {
// This variable was created during the fudging.
// Recreate it with a fresh variable here.
let idx = (vid.index - self.const_vars.0.start.index) as usize;
let origin = self.const_vars.1[idx];
self.infcx.next_const_var(ty, origin)
self.infcx.next_const_var(ct.ty, origin)
} else {
ct
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_infer/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};

let fld_c = |bound_var: ty::BoundVar, ty| {
self.tcx.mk_const(ty::Const {
val: ty::ConstKind::Placeholder(ty::PlaceholderConst {
self.tcx.mk_const(
ty,
ty::ConstKind::Placeholder(ty::PlaceholderConst {
universe: next_universe,
name: bound_var,
}),
ty,
})
)
};

let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/infer/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,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().mk_const(ty::Const { val: ty::ConstKind::Error, ty: c.ty });
return self.tcx().mk_const(c.ty, ty::ConstKind::Error);
}
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
bug!("Unexpected const in full const resolver: {:?}", c);
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_middle/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ macro_rules! arena_types {
// Interned types
[] tys: rustc_middle::ty::TyS<$tcx>,

[] const_: rustc_middle::ty::Const<$tcx>,

// HIR query types
[few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>,
[few] hir_definitions: rustc_hir::definitions::Definitions,
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_middle/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,10 @@ impl<'tcx> CanonicalVarValues<'tcx> {
.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i)))
.into(),
GenericArgKind::Const(ct) => tcx
.mk_const(ty::Const {
ty: ct.ty,
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
})
.mk_const(
ct.ty,
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
)
.into(),
})
.collect(),
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_middle/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,10 @@ pub fn decode_const<D>(decoder: &mut D) -> Result<&'tcx ty::Const<'tcx>, D::Erro
where
D: TyDecoder<'tcx>,
{
Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
// FIXME: we temporarily have a `Const` on the stack here,
// as we compare `Const`s using ptr equality, this is dangerous.
let ct: ty::Const<'tcx> = Decodable::decode(decoder)?;
Ok(decoder.tcx().mk_const(ct.ty, ct.val))
}

#[inline]
Expand Down
36 changes: 29 additions & 7 deletions src/librustc_middle/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ use crate::ty::TyKind::*;
use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
use crate::ty::{AdtDef, AdtKind, Const, Region};
use crate::ty::{BindingMode, BoundVar};
use crate::ty::{ConstKind, InferConst, ParamConst};
use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
use crate::ty::{ExistentialPredicate, Predicate, PredicateKind};
use crate::ty::{InferConst, ParamConst};
use crate::ty::{InferTy, ParamTy, PolyFnSig, ProjectionTy};
use crate::ty::{List, TyKind, TyS};
use rustc_ast::ast;
Expand Down Expand Up @@ -856,9 +856,10 @@ impl<'tcx> CommonConsts<'tcx> {
let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0;

CommonConsts {
unit: mk_const(ty::Const {
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
unit: mk_const(Const {
ty: types.unit,
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
_priv: ty::sty::PrivateMarker(()),
}),
}
}
Expand Down Expand Up @@ -1909,6 +1910,21 @@ impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
}
}

impl<'tcx> PartialEq for Interned<'tcx, Const<'tcx>> {
fn eq(&self, other: &Interned<'tcx, Const<'tcx>>) -> bool {
self.0.ty == other.0.ty && self.0.val == other.0.val
}
}

impl<'tcx> Eq for Interned<'tcx, Const<'tcx>> {}

impl<'tcx> Hash for Interned<'tcx, Const<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) {
self.0.ty.hash(s);
self.0.val.hash(s);
}
}

// N.B., an `Interned<List<T>>` compares and hashes as its elements.
impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> {
fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool {
Expand Down Expand Up @@ -2022,7 +2038,6 @@ macro_rules! direct_interners {

direct_interners!(
region: mk_region(RegionKind),
const_: mk_const(Const<'tcx>),
predicate_kind: intern_predicate_kind(PredicateKind<'tcx>),
);

Expand Down Expand Up @@ -2086,6 +2101,13 @@ impl<'tcx> TyCtxt<'tcx> {
self.interners.intern_ty(st)
}

#[inline]
pub fn mk_const(&self, ty: Ty<'tcx>, val: ConstKind<'tcx>) -> &'tcx Const<'tcx> {
let ct = Const { ty, val, _priv: super::sty::PrivateMarker(()) };

self.interners.const_.intern(ct, |ct| Interned(self.arena.alloc(ct))).0
}

#[inline]
pub fn mk_predicate(&self, kind: PredicateKind<'tcx>) -> Predicate<'tcx> {
let kind = self.intern_predicate_kind(kind);
Expand Down Expand Up @@ -2307,7 +2329,7 @@ impl<'tcx> TyCtxt<'tcx> {

#[inline]
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
self.mk_const(ty, ty::ConstKind::Infer(InferConst::Var(v)))
}

#[inline]
Expand All @@ -2327,7 +2349,7 @@ impl<'tcx> TyCtxt<'tcx> {

#[inline]
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(ic), ty })
self.mk_const(ty, ty::ConstKind::Infer(ic))
}

#[inline]
Expand All @@ -2337,7 +2359,7 @@ impl<'tcx> TyCtxt<'tcx> {

#[inline]
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
self.mk_const(ty, ty::ConstKind::Param(ParamConst { index, name }))
}

pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
Expand Down
12 changes: 5 additions & 7 deletions src/librustc_middle/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } = *ct {
if let ty::ConstKind::Bound(debruijn, bound_const) = ct.val {
if debruijn == self.current_index {
let fld_c = &mut self.fld_c;
let ct = fld_c(bound_const, ty);
let ct = fld_c(bound_const, ct.ty);
ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())
} else {
ct
Expand Down Expand Up @@ -551,9 +551,7 @@ impl<'tcx> TyCtxt<'tcx> {
{
// identity for bound types and consts
let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty));
let fld_c = |bound_ct, ty| {
self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty })
};
let fld_c = |bound_ct, ty| self.mk_const(ty, ty::ConstKind::Bound(ty::INNERMOST, bound_ct));
self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
}

Expand Down Expand Up @@ -788,7 +786,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.val {
if self.amount == 0 || debruijn < self.current_index {
ct
} else {
Expand All @@ -799,7 +797,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
debruijn.shifted_out(self.amount)
}
};
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
self.tcx.mk_const(ct.ty, ty::ConstKind::Bound(debruijn, bound_ct))
}
} else {
ct.super_fold_with(self)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_middle/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ pub trait PrettyPrinter<'tcx>:
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
let contents = self.tcx().destructure_const(
ty::ParamEnv::reveal_all()
.and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })),
.and(self.tcx().mk_const(ty, ty::ConstKind::Value(ct))),
);
let fields = contents.fields.iter().copied();

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_middle/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
}
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
};
new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty }))
new_const_val.map(|val| tcx.mk_const(a.ty, val))
}

impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_middle/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let ty = self.ty.fold_with(folder);
let val = self.val.fold_with(folder);
folder.tcx().mk_const(ty::Const { ty, val })
folder.tcx().mk_const(ty, val)
}

fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
Expand Down
29 changes: 24 additions & 5 deletions src/librustc_middle/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ use rustc_macros::HashStable;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_target::abi::{Size, VariantIdx};
use rustc_target::spec::abi;

use std::borrow::Cow;
use std::cmp::Ordering;
use std::marker::PhantomData;
use std::ops::Range;
use std::ptr;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable, Lift)]
Expand Down Expand Up @@ -2178,21 +2180,38 @@ impl<'tcx> TyS<'tcx> {
}

/// Typed constant value.
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Debug, Hash, RustcEncodable, RustcDecodable, Eq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct Const<'tcx> {
pub ty: Ty<'tcx>,

pub val: ConstKind<'tcx>,

/// We compare `Const` by pointer equality. This would be incorrect
/// if we were able to create Const values on the stack.
///
/// Only allow the creation of consts using `tcx.mk_const(ty, val)`.
pub _priv: PrivateMarker,
}

impl<'tcx> PartialEq for Const<'tcx> {
fn eq(&self, other: &Const<'tcx>) -> bool {
// All `Const` should be interned.
ptr::eq(self, other)
}
}

#[derive(Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct PrivateMarker(pub(super) ());

#[cfg(target_arch = "x86_64")]
static_assert_size!(Const<'_>, 48);

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) -> &'tcx Self {
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Const<'tcx> {
debug!("Const::from_anon_const(id={:?})", def_id);

let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
Expand Down Expand Up @@ -2260,13 +2279,13 @@ impl<'tcx> Const<'tcx> {
),
};

tcx.mk_const(ty::Const { val, ty })
tcx.mk_const(ty, val)
}

#[inline]
/// Interns the given value as a constant.
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
tcx.mk_const(Self { val: ConstKind::Value(val), ty })
tcx.mk_const(ty, ConstKind::Value(val))
}

#[inline]
Expand Down Expand Up @@ -2357,7 +2376,7 @@ impl<'tcx> Const<'tcx> {
Ok(val) => Const::from_value(tcx, val, self.ty),
Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
Err(ErrorHandled::Reported(ErrorReported)) => {
tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: self.ty })
tcx.mk_const(self.ty, ty::ConstKind::Error)
}
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,8 +849,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
// return `ConstValue::Unevaluated`, which is the only way that `eval_const_to_op` will call
// `ecx.const_eval`.
let const_ = ty::Const { val: ty::ConstKind::Value(val), ty };
self.eval_const_to_op(&const_, None)
let const_ = self.tcx.mk_const(ty, ty::ConstKind::Value(val));
self.eval_const_to_op(const_, None)
}

pub fn const_eval_raw(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
Operand::Constant(Box::new(Constant {
span,
user_ty: None,
literal: self.tcx.mk_const(*ty::Const::from_scalar(self.tcx, scalar, ty)),
literal: ty::Const::from_scalar(self.tcx, scalar, ty),
}))
}

Expand Down
6 changes: 3 additions & 3 deletions src/librustc_mir/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,9 +954,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
Operand::Constant(Box::new(Constant {
span,
user_ty: None,
literal: tcx.mk_const(ty::Const {
literal: tcx.mk_const(
ty,
val: ty::ConstKind::Unevaluated(
ty::ConstKind::Unevaluated(
def_id,
InternalSubsts::for_item(tcx, def_id, |param, _| {
if let ty::GenericParamDefKind::Lifetime = param.kind {
Expand All @@ -967,7 +967,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}),
Some(promoted_id),
),
}),
),
}))
};
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
Expand Down
Loading

0 comments on commit ef5aa6a

Please sign in to comment.