Skip to content

Commit ef5aa6a

Browse files
committed
compare consts using ptr equality
1 parent 783139b commit ef5aa6a

File tree

26 files changed

+114
-71
lines changed

26 files changed

+114
-71
lines changed

src/librustc_infer/infer/canonical/canonicalizer.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -658,10 +658,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
658658
self.fold_const(bound_to)
659659
} else {
660660
let var = self.canonical_var(info, const_var.into());
661-
self.tcx().mk_const(ty::Const {
662-
val: ty::ConstKind::Bound(self.binder_index, var),
663-
ty: self.fold_ty(const_var.ty),
664-
})
661+
self.tcx()
662+
.mk_const(self.fold_ty(const_var.ty), ty::ConstKind::Bound(self.binder_index, var))
665663
}
666664
}
667665
}

src/librustc_infer/infer/canonical/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
152152
let universe_mapped = universe_map(universe);
153153
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name };
154154
self.tcx
155-
.mk_const(ty::Const {
156-
val: ty::ConstKind::Placeholder(placeholder_mapped),
157-
ty: self.tcx.types.err, // FIXME(const_generics)
158-
})
155+
.mk_const(
156+
self.tcx.types.err, // FIXME(const_generics)
157+
ty::ConstKind::Placeholder(placeholder_mapped),
158+
)
159159
.into()
160160
}
161161
}

src/librustc_infer/infer/fudge.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
232232
}
233233

234234
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
235-
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
235+
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.val {
236236
if self.const_vars.0.contains(&vid) {
237237
// This variable was created during the fudging.
238238
// Recreate it with a fresh variable here.
239239
let idx = (vid.index - self.const_vars.0.start.index) as usize;
240240
let origin = self.const_vars.1[idx];
241-
self.infcx.next_const_var(ty, origin)
241+
self.infcx.next_const_var(ct.ty, origin)
242242
} else {
243243
ct
244244
}

src/librustc_infer/infer/higher_ranked/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9898
};
9999

100100
let fld_c = |bound_var: ty::BoundVar, ty| {
101-
self.tcx.mk_const(ty::Const {
102-
val: ty::ConstKind::Placeholder(ty::PlaceholderConst {
101+
self.tcx.mk_const(
102+
ty,
103+
ty::ConstKind::Placeholder(ty::PlaceholderConst {
103104
universe: next_universe,
104105
name: bound_var,
105106
}),
106-
ty,
107-
})
107+
)
108108
};
109109

110110
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);

src/librustc_infer/infer/resolve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
228228
match c.val {
229229
ty::ConstKind::Infer(InferConst::Var(vid)) => {
230230
self.err = Some(FixupError::UnresolvedConst(vid));
231-
return self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: c.ty });
231+
return self.tcx().mk_const(c.ty, ty::ConstKind::Error);
232232
}
233233
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
234234
bug!("Unexpected const in full const resolver: {:?}", c);

src/librustc_middle/arena.rs

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ macro_rules! arena_types {
7171
// Interned types
7272
[] tys: rustc_middle::ty::TyS<$tcx>,
7373

74+
[] const_: rustc_middle::ty::Const<$tcx>,
75+
7476
// HIR query types
7577
[few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>,
7678
[few] hir_definitions: rustc_hir::definitions::Definitions,

src/librustc_middle/infer/canonical.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -328,10 +328,10 @@ impl<'tcx> CanonicalVarValues<'tcx> {
328328
.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i)))
329329
.into(),
330330
GenericArgKind::Const(ct) => tcx
331-
.mk_const(ty::Const {
332-
ty: ct.ty,
333-
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
334-
})
331+
.mk_const(
332+
ct.ty,
333+
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
334+
)
335335
.into(),
336336
})
337337
.collect(),

src/librustc_middle/ty/codec.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,10 @@ pub fn decode_const<D>(decoder: &mut D) -> Result<&'tcx ty::Const<'tcx>, D::Erro
291291
where
292292
D: TyDecoder<'tcx>,
293293
{
294-
Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
294+
// FIXME: we temporarily have a `Const` on the stack here,
295+
// as we compare `Const`s using ptr equality, this is dangerous.
296+
let ct: ty::Const<'tcx> = Decodable::decode(decoder)?;
297+
Ok(decoder.tcx().mk_const(ct.ty, ct.val))
295298
}
296299

297300
#[inline]

src/librustc_middle/ty/context.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ use crate::ty::TyKind::*;
2828
use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
2929
use crate::ty::{AdtDef, AdtKind, Const, Region};
3030
use crate::ty::{BindingMode, BoundVar};
31+
use crate::ty::{ConstKind, InferConst, ParamConst};
3132
use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
3233
use crate::ty::{ExistentialPredicate, Predicate, PredicateKind};
33-
use crate::ty::{InferConst, ParamConst};
3434
use crate::ty::{InferTy, ParamTy, PolyFnSig, ProjectionTy};
3535
use crate::ty::{List, TyKind, TyS};
3636
use rustc_ast::ast;
@@ -856,9 +856,10 @@ impl<'tcx> CommonConsts<'tcx> {
856856
let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0;
857857

858858
CommonConsts {
859-
unit: mk_const(ty::Const {
860-
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
859+
unit: mk_const(Const {
861860
ty: types.unit,
861+
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
862+
_priv: ty::sty::PrivateMarker(()),
862863
}),
863864
}
864865
}
@@ -1909,6 +1910,21 @@ impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
19091910
}
19101911
}
19111912

1913+
impl<'tcx> PartialEq for Interned<'tcx, Const<'tcx>> {
1914+
fn eq(&self, other: &Interned<'tcx, Const<'tcx>>) -> bool {
1915+
self.0.ty == other.0.ty && self.0.val == other.0.val
1916+
}
1917+
}
1918+
1919+
impl<'tcx> Eq for Interned<'tcx, Const<'tcx>> {}
1920+
1921+
impl<'tcx> Hash for Interned<'tcx, Const<'tcx>> {
1922+
fn hash<H: Hasher>(&self, s: &mut H) {
1923+
self.0.ty.hash(s);
1924+
self.0.val.hash(s);
1925+
}
1926+
}
1927+
19121928
// N.B., an `Interned<List<T>>` compares and hashes as its elements.
19131929
impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> {
19141930
fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool {
@@ -2022,7 +2038,6 @@ macro_rules! direct_interners {
20222038

20232039
direct_interners!(
20242040
region: mk_region(RegionKind),
2025-
const_: mk_const(Const<'tcx>),
20262041
predicate_kind: intern_predicate_kind(PredicateKind<'tcx>),
20272042
);
20282043

@@ -2086,6 +2101,13 @@ impl<'tcx> TyCtxt<'tcx> {
20862101
self.interners.intern_ty(st)
20872102
}
20882103

2104+
#[inline]
2105+
pub fn mk_const(&self, ty: Ty<'tcx>, val: ConstKind<'tcx>) -> &'tcx Const<'tcx> {
2106+
let ct = Const { ty, val, _priv: super::sty::PrivateMarker(()) };
2107+
2108+
self.interners.const_.intern(ct, |ct| Interned(self.arena.alloc(ct))).0
2109+
}
2110+
20892111
#[inline]
20902112
pub fn mk_predicate(&self, kind: PredicateKind<'tcx>) -> Predicate<'tcx> {
20912113
let kind = self.intern_predicate_kind(kind);
@@ -2307,7 +2329,7 @@ impl<'tcx> TyCtxt<'tcx> {
23072329

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

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

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

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

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

23432365
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {

src/librustc_middle/ty/fold.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -509,10 +509,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
509509
}
510510

511511
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
512-
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } = *ct {
512+
if let ty::ConstKind::Bound(debruijn, bound_const) = ct.val {
513513
if debruijn == self.current_index {
514514
let fld_c = &mut self.fld_c;
515-
let ct = fld_c(bound_const, ty);
515+
let ct = fld_c(bound_const, ct.ty);
516516
ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())
517517
} else {
518518
ct
@@ -551,9 +551,7 @@ impl<'tcx> TyCtxt<'tcx> {
551551
{
552552
// identity for bound types and consts
553553
let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty));
554-
let fld_c = |bound_ct, ty| {
555-
self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty })
556-
};
554+
let fld_c = |bound_ct, ty| self.mk_const(ty, ty::ConstKind::Bound(ty::INNERMOST, bound_ct));
557555
self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
558556
}
559557

@@ -788,7 +786,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
788786
}
789787

790788
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
791-
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
789+
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.val {
792790
if self.amount == 0 || debruijn < self.current_index {
793791
ct
794792
} else {
@@ -799,7 +797,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
799797
debruijn.shifted_out(self.amount)
800798
}
801799
};
802-
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
800+
self.tcx.mk_const(ct.ty, ty::ConstKind::Bound(debruijn, bound_ct))
803801
}
804802
} else {
805803
ct.super_fold_with(self)

src/librustc_middle/ty/print/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ pub trait PrettyPrinter<'tcx>:
11601160
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
11611161
let contents = self.tcx().destructure_const(
11621162
ty::ParamEnv::reveal_all()
1163-
.and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })),
1163+
.and(self.tcx().mk_const(ty, ty::ConstKind::Value(ct))),
11641164
);
11651165
let fields = contents.fields.iter().copied();
11661166

src/librustc_middle/ty/relate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
617617
}
618618
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
619619
};
620-
new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty }))
620+
new_const_val.map(|val| tcx.mk_const(a.ty, val))
621621
}
622622

623623
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {

src/librustc_middle/ty/structural_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
10191019
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
10201020
let ty = self.ty.fold_with(folder);
10211021
let val = self.val.fold_with(folder);
1022-
folder.tcx().mk_const(ty::Const { ty, val })
1022+
folder.tcx().mk_const(ty, val)
10231023
}
10241024

10251025
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {

src/librustc_middle/ty/sty.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ use rustc_macros::HashStable;
2525
use rustc_span::symbol::{kw, Ident, Symbol};
2626
use rustc_target::abi::{Size, VariantIdx};
2727
use rustc_target::spec::abi;
28+
2829
use std::borrow::Cow;
2930
use std::cmp::Ordering;
3031
use std::marker::PhantomData;
3132
use std::ops::Range;
33+
use std::ptr;
3234

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

21802182
/// Typed constant value.
2181-
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
2183+
#[derive(Debug, Hash, RustcEncodable, RustcDecodable, Eq, Ord, PartialOrd)]
21822184
#[derive(HashStable)]
21832185
pub struct Const<'tcx> {
21842186
pub ty: Ty<'tcx>,
21852187

21862188
pub val: ConstKind<'tcx>,
2189+
2190+
/// We compare `Const` by pointer equality. This would be incorrect
2191+
/// if we were able to create Const values on the stack.
2192+
///
2193+
/// Only allow the creation of consts using `tcx.mk_const(ty, val)`.
2194+
pub _priv: PrivateMarker,
2195+
}
2196+
2197+
impl<'tcx> PartialEq for Const<'tcx> {
2198+
fn eq(&self, other: &Const<'tcx>) -> bool {
2199+
// All `Const` should be interned.
2200+
ptr::eq(self, other)
2201+
}
21872202
}
21882203

2204+
#[derive(Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
2205+
#[derive(HashStable)]
2206+
pub struct PrivateMarker(pub(super) ());
2207+
21892208
#[cfg(target_arch = "x86_64")]
21902209
static_assert_size!(Const<'_>, 48);
21912210

21922211
impl<'tcx> Const<'tcx> {
21932212
/// Literals and const generic parameters are eagerly converted to a constant, everything else
21942213
/// becomes `Unevaluated`.
2195-
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
2214+
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Const<'tcx> {
21962215
debug!("Const::from_anon_const(id={:?})", def_id);
21972216

21982217
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
@@ -2260,13 +2279,13 @@ impl<'tcx> Const<'tcx> {
22602279
),
22612280
};
22622281

2263-
tcx.mk_const(ty::Const { val, ty })
2282+
tcx.mk_const(ty, val)
22642283
}
22652284

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

22722291
#[inline]
@@ -2357,7 +2376,7 @@ impl<'tcx> Const<'tcx> {
23572376
Ok(val) => Const::from_value(tcx, val, self.ty),
23582377
Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
23592378
Err(ErrorHandled::Reported(ErrorReported)) => {
2360-
tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: self.ty })
2379+
tcx.mk_const(self.ty, ty::ConstKind::Error)
23612380
}
23622381
}
23632382
} else {

src/librustc_mir/interpret/eval_context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -849,8 +849,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
849849
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
850850
// return `ConstValue::Unevaluated`, which is the only way that `eval_const_to_op` will call
851851
// `ecx.const_eval`.
852-
let const_ = ty::Const { val: ty::ConstKind::Value(val), ty };
853-
self.eval_const_to_op(&const_, None)
852+
let const_ = self.tcx.mk_const(ty, ty::ConstKind::Value(val));
853+
self.eval_const_to_op(const_, None)
854854
}
855855

856856
pub fn const_eval_raw(

src/librustc_mir/transform/const_prop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
606606
Operand::Constant(Box::new(Constant {
607607
span,
608608
user_ty: None,
609-
literal: self.tcx.mk_const(*ty::Const::from_scalar(self.tcx, scalar, ty)),
609+
literal: ty::Const::from_scalar(self.tcx, scalar, ty),
610610
}))
611611
}
612612

src/librustc_mir/transform/promote_consts.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -954,9 +954,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
954954
Operand::Constant(Box::new(Constant {
955955
span,
956956
user_ty: None,
957-
literal: tcx.mk_const(ty::Const {
957+
literal: tcx.mk_const(
958958
ty,
959-
val: ty::ConstKind::Unevaluated(
959+
ty::ConstKind::Unevaluated(
960960
def_id,
961961
InternalSubsts::for_item(tcx, def_id, |param, _| {
962962
if let ty::GenericParamDefKind::Lifetime = param.kind {
@@ -967,7 +967,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
967967
}),
968968
Some(promoted_id),
969969
),
970-
}),
970+
),
971971
}))
972972
};
973973
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();

0 commit comments

Comments
 (0)