Skip to content

Commit 80e1ee5

Browse files
committed
Add ty::BoundConstness
1 parent c75aeaa commit 80e1ee5

File tree

18 files changed

+80
-80
lines changed

18 files changed

+80
-80
lines changed

compiler/rustc_middle/src/traits/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use rustc_data_structures::sync::Lrc;
1717
use rustc_errors::{Applicability, DiagnosticBuilder};
1818
use rustc_hir as hir;
1919
use rustc_hir::def_id::{DefId, LocalDefId};
20-
use rustc_hir::Constness;
2120
use rustc_span::symbol::Symbol;
2221
use rustc_span::{Span, DUMMY_SP};
2322
use smallvec::SmallVec;
@@ -497,7 +496,7 @@ pub enum ImplSource<'tcx, N> {
497496
/// for some type parameter. The `Vec<N>` represents the
498497
/// obligations incurred from normalizing the where-clause (if
499498
/// any).
500-
Param(Vec<N>, Constness),
499+
Param(Vec<N>, ty::BoundConstness),
501500

502501
/// Virtual calls through an object.
503502
Object(ImplSourceObjectData<'tcx, N>),

compiler/rustc_middle/src/ty/error.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl<T> ExpectedFound<T> {
3333
#[derive(Clone, Debug, TypeFoldable)]
3434
pub enum TypeError<'tcx> {
3535
Mismatch,
36-
ConstnessMismatch(ExpectedFound<hir::Constness>),
36+
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
3737
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
3838
AbiMismatch(ExpectedFound<abi::Abi>),
3939
Mutability,
@@ -102,7 +102,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
102102
CyclicConst(_) => write!(f, "encountered a self-referencing constant"),
103103
Mismatch => write!(f, "types differ"),
104104
ConstnessMismatch(values) => {
105-
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
105+
write!(f, "expected {} bound, found {} bound", values.expected, values.found)
106106
}
107107
UnsafetyMismatch(values) => {
108108
write!(f, "expected {} fn, found {} fn", values.expected, values.found)

compiler/rustc_middle/src/ty/mod.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
3737
use rustc_hir as hir;
3838
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
3939
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_INDEX};
40-
use rustc_hir::{Constness, Node};
40+
use rustc_hir::Node;
4141
use rustc_macros::HashStable;
4242
use rustc_span::symbol::{kw, Ident, Symbol};
4343
use rustc_span::Span;
@@ -181,6 +181,25 @@ pub enum Visibility {
181181
Invisible,
182182
}
183183

184+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
185+
pub enum BoundConstness {
186+
/// `T: Trait`
187+
NotConst,
188+
/// `T: ~const Trait`
189+
///
190+
/// Requires resolving to const only when we are in a const context.
191+
ConstIfConst,
192+
}
193+
194+
impl fmt::Display for BoundConstness {
195+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196+
match self {
197+
Self::NotConst => f.write_str("normal"),
198+
Self::ConstIfConst => f.write_str("`~const`"),
199+
}
200+
}
201+
}
202+
184203
#[derive(
185204
Clone,
186205
Debug,
@@ -628,9 +647,7 @@ impl<'tcx> Predicate<'tcx> {
628647
pub struct TraitPredicate<'tcx> {
629648
pub trait_ref: TraitRef<'tcx>,
630649

631-
/// A trait predicate will have `Constness::Const` if it originates
632-
/// from a bound marked with `~const`.
633-
pub constness: hir::Constness,
650+
pub constness: BoundConstness,
634651
}
635652

636653
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
@@ -1299,26 +1316,26 @@ impl<'tcx> ParamEnv<'tcx> {
12991316

13001317
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
13011318
pub struct ConstnessAnd<T> {
1302-
pub constness: Constness,
1319+
pub constness: BoundConstness,
13031320
pub value: T,
13041321
}
13051322

13061323
// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate(tcx)` to ensure that
13071324
// the constness of trait bounds is being propagated correctly.
13081325
pub trait WithConstness: Sized {
13091326
#[inline]
1310-
fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> {
1327+
fn with_constness(self, constness: BoundConstness) -> ConstnessAnd<Self> {
13111328
ConstnessAnd { constness, value: self }
13121329
}
13131330

13141331
#[inline]
1315-
fn with_const(self) -> ConstnessAnd<Self> {
1316-
self.with_constness(Constness::Const)
1332+
fn with_const_if_const(self) -> ConstnessAnd<Self> {
1333+
self.with_constness(BoundConstness::ConstIfConst)
13171334
}
13181335

13191336
#[inline]
13201337
fn without_const(self) -> ConstnessAnd<Self> {
1321-
self.with_constness(Constness::NotConst)
1338+
self.with_constness(BoundConstness::NotConst)
13221339
}
13231340
}
13241341

compiler/rustc_middle/src/ty/relate.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,12 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
200200
}
201201
}
202202

203-
impl<'tcx> Relate<'tcx> for ast::Constness {
203+
impl<'tcx> Relate<'tcx> for ty::BoundConstness {
204204
fn relate<R: TypeRelation<'tcx>>(
205205
relation: &mut R,
206-
a: ast::Constness,
207-
b: ast::Constness,
208-
) -> RelateResult<'tcx, ast::Constness> {
206+
a: ty::BoundConstness,
207+
b: ty::BoundConstness,
208+
) -> RelateResult<'tcx, ty::BoundConstness> {
209209
if a != b {
210210
Err(TypeError::ConstnessMismatch(expected_found(relation, a, b)))
211211
} else {

compiler/rustc_middle/src/ty/structural_impls.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
88
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
99
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
1010
use rustc_data_structures::functor::IdFunctor;
11-
use rustc_hir as hir;
1211
use rustc_hir::def::Namespace;
1312
use rustc_hir::def_id::CRATE_DEF_INDEX;
1413
use rustc_index::vec::{Idx, IndexVec};
@@ -155,8 +154,8 @@ impl fmt::Debug for ty::ParamConst {
155154

156155
impl fmt::Debug for ty::TraitPredicate<'tcx> {
157156
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158-
if let hir::Constness::Const = self.constness {
159-
write!(f, "const ")?;
157+
if let ty::BoundConstness::ConstIfConst = self.constness {
158+
write!(f, "~const ")?;
160159
}
161160
write!(f, "TraitPredicate({:?})", self.trait_ref)
162161
}
@@ -241,6 +240,7 @@ TrivialTypeFoldableAndLiftImpls! {
241240
crate::traits::Reveal,
242241
crate::ty::adjustment::AutoBorrowMutability,
243242
crate::ty::AdtKind,
243+
crate::ty::BoundConstness,
244244
// Including `BoundRegionKind` is a *bit* dubious, but direct
245245
// references to bound region appear in `ty::Error`, and aren't
246246
// really meant to be folded. In general, we can only fold a fully

compiler/rustc_middle/src/ty/sty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
878878
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
879879
self.map_bound(|trait_ref| ty::TraitPredicate {
880880
trait_ref,
881-
constness: hir::Constness::NotConst,
881+
constness: ty::BoundConstness::NotConst,
882882
})
883883
}
884884
}

compiler/rustc_mir/src/borrow_check/type_check/canonical.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::fmt;
22

3-
use rustc_hir as hir;
43
use rustc_infer::infer::canonical::Canonical;
54
use rustc_infer::traits::query::NoSolution;
65
use rustc_middle::mir::ConstraintCategory;
@@ -88,7 +87,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
8887
self.prove_predicates(
8988
Some(ty::PredicateKind::Trait(ty::TraitPredicate {
9089
trait_ref,
91-
constness: hir::Constness::NotConst,
90+
constness: ty::BoundConstness::NotConst,
9291
})),
9392
locations,
9493
category,

compiler/rustc_mir/src/transform/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
821821
param_env,
822822
Binder::dummy(TraitPredicate {
823823
trait_ref,
824-
constness: hir::Constness::Const,
824+
constness: ty::BoundConstness::ConstIfConst,
825825
}),
826826
);
827827

@@ -831,7 +831,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
831831
});
832832

833833
match implsrc {
834-
Ok(Some(ImplSource::Param(_, hir::Constness::Const))) => {
834+
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
835835
debug!(
836836
"const_trait_impl: provided {:?} via where-clause in {:?}",
837837
trait_ref, param_env

compiler/rustc_trait_selection/src/traits/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ impl AutoTraitFinder<'tcx> {
285285
def_id: trait_did,
286286
substs: infcx.tcx.mk_substs_trait(ty, &[]),
287287
},
288-
constness: hir::Constness::NotConst,
288+
constness: ty::BoundConstness::NotConst,
289289
}));
290290

291291
let computed_preds = param_env.caller_bounds().iter();

compiler/rustc_trait_selection/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot(
778778
let obligation = Obligation::new(
779779
ObligationCause::dummy(),
780780
ty::ParamEnv::reveal_all(),
781-
ty::Binder::dummy(ty::TraitPredicate { trait_ref, constness: hir::Constness::NotConst }),
781+
ty::Binder::dummy(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst }),
782782
);
783783

784784
let implsrc = tcx.infer_ctxt().enter(|infcx| {

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
99
use rustc_data_structures::stack::ensure_sufficient_stack;
1010
use rustc_hir::lang_items::LangItem;
11-
use rustc_hir::Constness;
1211
use rustc_index::bit_set::GrowableBitSet;
1312
use rustc_infer::infer::InferOk;
1413
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
@@ -75,7 +74,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
7574
ProjectionCandidate(idx) => {
7675
let obligations = self.confirm_projection_candidate(obligation, idx)?;
7776
// FIXME(jschievink): constness
78-
Ok(ImplSource::Param(obligations, Constness::NotConst))
77+
Ok(ImplSource::Param(obligations, ty::BoundConstness::NotConst))
7978
}
8079

8180
ObjectCandidate(idx) => {
@@ -113,7 +112,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
113112
// This indicates something like `Trait + Send: Send`. In this case, we know that
114113
// this holds because that's what the object type is telling us, and there's really
115114
// no additional obligations to prove and no types in particular to unify, etc.
116-
Ok(ImplSource::Param(Vec::new(), Constness::NotConst))
115+
Ok(ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst))
117116
}
118117

119118
BuiltinUnsizeCandidate => {

compiler/rustc_trait_selection/src/traits/select/mod.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use rustc_data_structures::sync::Lrc;
3232
use rustc_errors::ErrorReported;
3333
use rustc_hir as hir;
3434
use rustc_hir::def_id::DefId;
35-
use rustc_hir::Constness;
3635
use rustc_infer::infer::LateBoundRegionConversionTime;
3736
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
3837
use rustc_middle::mir::abstract_const::NotConstEvaluatable;
@@ -130,8 +129,8 @@ pub struct SelectionContext<'cx, 'tcx> {
130129
/// and a negative impl
131130
allow_negative_impls: bool,
132131

133-
/// Do we only want const impls when we have a const trait predicate?
134-
const_impls_required: bool,
132+
/// Are we in a const context that needs `~const` bounds to be const?
133+
is_in_const_context: bool,
135134

136135
/// The mode that trait queries run in, which informs our error handling
137136
/// policy. In essence, canonicalized queries need their errors propagated
@@ -224,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
224223
intercrate: false,
225224
intercrate_ambiguity_causes: None,
226225
allow_negative_impls: false,
227-
const_impls_required: false,
226+
is_in_const_context: false,
228227
query_mode: TraitQueryMode::Standard,
229228
}
230229
}
@@ -236,7 +235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
236235
intercrate: true,
237236
intercrate_ambiguity_causes: None,
238237
allow_negative_impls: false,
239-
const_impls_required: false,
238+
is_in_const_context: false,
240239
query_mode: TraitQueryMode::Standard,
241240
}
242241
}
@@ -252,7 +251,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
252251
intercrate: false,
253252
intercrate_ambiguity_causes: None,
254253
allow_negative_impls,
255-
const_impls_required: false,
254+
is_in_const_context: false,
256255
query_mode: TraitQueryMode::Standard,
257256
}
258257
}
@@ -268,7 +267,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
268267
intercrate: false,
269268
intercrate_ambiguity_causes: None,
270269
allow_negative_impls: false,
271-
const_impls_required: false,
270+
is_in_const_context: false,
272271
query_mode,
273272
}
274273
}
@@ -283,7 +282,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
283282
intercrate: false,
284283
intercrate_ambiguity_causes: None,
285284
allow_negative_impls: false,
286-
const_impls_required: matches!(constness, hir::Constness::Const),
285+
is_in_const_context: matches!(constness, hir::Constness::Const),
287286
query_mode: TraitQueryMode::Standard,
288287
}
289288
}
@@ -316,14 +315,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
316315
self.infcx.tcx
317316
}
318317

318+
/// Returns `true` if the trait predicate is considerd `const` to this selection context.
319+
pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool {
320+
match pred.constness {
321+
ty::BoundConstness::ConstIfConst if self.is_in_const_context => true,
322+
_ => false
323+
}
324+
}
325+
319326
/// Returns `true` if the predicate is considered `const` to
320327
/// this selection context.
321328
pub fn is_predicate_const(&self, pred: ty::Predicate<'_>) -> bool {
322329
match pred.kind().skip_binder() {
323-
ty::PredicateKind::Trait(ty::TraitPredicate {
324-
constness: hir::Constness::Const,
325-
..
326-
}) if self.const_impls_required => true,
330+
ty::PredicateKind::Trait(pred) => self.is_trait_predicate_const(pred),
327331
_ => false,
328332
}
329333
}
@@ -1074,8 +1078,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10741078
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
10751079
let tcx = self.tcx();
10761080
// Respect const trait obligations
1077-
if self.const_impls_required {
1078-
if let hir::Constness::Const = obligation.predicate.skip_binder().constness {
1081+
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
10791082
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
10801083
!= tcx.lang_items().sized_trait()
10811084
// const Sized bounds are skipped
@@ -1086,7 +1089,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10861089
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
10871090
// const param
10881091
ParamCandidate(ty::ConstnessAnd {
1089-
constness: hir::Constness::Const,
1092+
constness: ty::BoundConstness::ConstIfConst,
10901093
..
10911094
}) => {}
10921095
// auto trait impl
@@ -1100,7 +1103,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11001103
}
11011104
}
11021105
}
1103-
}
11041106
}
11051107
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
11061108
if let ImplCandidate(def_id) = candidate {
@@ -1495,7 +1497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14951497
// probably best characterized as a "hack", since we might prefer to just do our
14961498
// best to *not* create essentially duplicate candidates in the first place.
14971499
other.value.bound_vars().len() <= victim.value.bound_vars().len()
1498-
} else if other.value == victim.value && victim.constness == Constness::NotConst {
1500+
} else if other.value == victim.value && victim.constness == ty::BoundConstness::NotConst {
14991501
// Drop otherwise equivalent non-const candidates in favor of const candidates.
15001502
true
15011503
} else {

0 commit comments

Comments
 (0)