Skip to content

Commit 721ffd1

Browse files
oli-obkfee1-dead
authored andcommitted
Add constness to ParamEnv
This now causes a lot of queries to be executed twice, as reveal_all forces NotConst
1 parent 22eeff7 commit 721ffd1

File tree

8 files changed

+127
-46
lines changed

8 files changed

+127
-46
lines changed

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,18 +454,30 @@ impl<'hir> Map<'hir> {
454454
///
455455
/// Panics if `LocalDefId` does not have an associated body.
456456
pub fn body_owner_kind(&self, id: HirId) -> BodyOwnerKind {
457+
match self.opt_body_owner_kind(id) {
458+
Ok(kind) => kind,
459+
Err(node) => bug!("{:#?} is not a body node", node),
460+
}
461+
}
462+
463+
/// Returns the `BodyOwnerKind` of this `LocalDefId`.
464+
///
465+
/// Returns the `Node` if `LocalDefId` does not have an associated body.
466+
pub fn opt_body_owner_kind(&self, id: HirId) -> Result<BodyOwnerKind, Node<'_>> {
457467
match self.get(id) {
458468
Node::Item(&Item { kind: ItemKind::Const(..), .. })
459469
| Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. })
460470
| Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. })
461-
| Node::AnonConst(_) => BodyOwnerKind::Const,
471+
| Node::AnonConst(_) => Ok(BodyOwnerKind::Const),
462472
Node::Ctor(..)
463473
| Node::Item(&Item { kind: ItemKind::Fn(..), .. })
464474
| Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(..), .. })
465-
| Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(..), .. }) => BodyOwnerKind::Fn,
466-
Node::Item(&Item { kind: ItemKind::Static(_, m, _), .. }) => BodyOwnerKind::Static(m),
467-
Node::Expr(&Expr { kind: ExprKind::Closure(..), .. }) => BodyOwnerKind::Closure,
468-
node => bug!("{:#?} is not a body node", node),
475+
| Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(..), .. }) => Ok(BodyOwnerKind::Fn),
476+
Node::Item(&Item { kind: ItemKind::Static(_, m, _), .. }) => {
477+
Ok(BodyOwnerKind::Static(m))
478+
}
479+
Node::Expr(&Expr { kind: ExprKind::Closure(..), .. }) => Ok(BodyOwnerKind::Closure),
480+
node => Err(node),
469481
}
470482
}
471483

@@ -474,7 +486,8 @@ impl<'hir> Map<'hir> {
474486
/// Panics if `LocalDefId` does not have an associated body.
475487
///
476488
/// This should only be used for determining the context of a body, a return
477-
/// value of `Some` does not always suggest that the owner of the body is `const`.
489+
/// value of `Some` does not always suggest that the owner of the body is `const`,
490+
/// just that it has to be checked as if it were.
478491
pub fn body_const_context(&self, did: LocalDefId) -> Option<ConstContext> {
479492
let hir_id = self.local_def_id_to_hir_id(did);
480493
let ccx = match self.body_owner_kind(hir_id) {

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,22 +1227,27 @@ pub struct ParamEnv<'tcx> {
12271227
#[derive(Copy, Clone)]
12281228
struct ParamTag {
12291229
reveal: traits::Reveal,
1230+
constness: hir::Constness,
12301231
}
12311232

12321233
unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
1233-
const BITS: usize = 1;
1234+
const BITS: usize = 2;
12341235
#[inline]
12351236
fn into_usize(self) -> usize {
12361237
match self {
1237-
Self { reveal: traits::Reveal::UserFacing } => 0,
1238-
Self { reveal: traits::Reveal::All } => 1,
1238+
Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 0,
1239+
Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 1,
1240+
Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 2,
1241+
Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3,
12391242
}
12401243
}
12411244
#[inline]
12421245
unsafe fn from_usize(ptr: usize) -> Self {
12431246
match ptr {
1244-
0 => Self { reveal: traits::Reveal::UserFacing },
1245-
1 => Self { reveal: traits::Reveal::All },
1247+
0 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst },
1248+
1 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst },
1249+
2 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const },
1250+
3 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const },
12461251
_ => std::hint::unreachable_unchecked(),
12471252
}
12481253
}
@@ -1253,6 +1258,7 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
12531258
f.debug_struct("ParamEnv")
12541259
.field("caller_bounds", &self.caller_bounds())
12551260
.field("reveal", &self.reveal())
1261+
.field("constness", &self.constness())
12561262
.finish()
12571263
}
12581264
}
@@ -1261,20 +1267,23 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
12611267
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
12621268
self.caller_bounds().hash_stable(hcx, hasher);
12631269
self.reveal().hash_stable(hcx, hasher);
1270+
self.constness().hash_stable(hcx, hasher);
12641271
}
12651272
}
12661273

12671274
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
1268-
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(
1269-
self,
1270-
folder: &mut F,
1271-
) -> Result<Self, F::Error> {
1272-
Ok(ParamEnv::new(self.caller_bounds().fold_with(folder)?, self.reveal().fold_with(folder)?))
1275+
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
1276+
ParamEnv::new(
1277+
self.caller_bounds().fold_with(folder)?,
1278+
self.reveal().fold_with(folder)?,
1279+
self.constness().fold_with(folder)?,
1280+
)
12731281
}
12741282

12751283
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
12761284
self.caller_bounds().visit_with(visitor)?;
1277-
self.reveal().visit_with(visitor)
1285+
self.reveal().visit_with(visitor)?;
1286+
self.constness().visit_with(visitor)
12781287
}
12791288
}
12801289

@@ -1285,7 +1294,7 @@ impl<'tcx> ParamEnv<'tcx> {
12851294
/// type-checking.
12861295
#[inline]
12871296
pub fn empty() -> Self {
1288-
Self::new(List::empty(), Reveal::UserFacing)
1297+
Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst)
12891298
}
12901299

12911300
#[inline]
@@ -1298,6 +1307,11 @@ impl<'tcx> ParamEnv<'tcx> {
12981307
self.packed.tag().reveal
12991308
}
13001309

1310+
#[inline]
1311+
pub fn constness(self) -> hir::Constness {
1312+
self.packed.tag().constness
1313+
}
1314+
13011315
/// Construct a trait environment with no where-clauses in scope
13021316
/// where the values of all `impl Trait` and other hidden types
13031317
/// are revealed. This is suitable for monomorphized, post-typeck
@@ -1307,13 +1321,17 @@ impl<'tcx> ParamEnv<'tcx> {
13071321
/// or invoke `param_env.with_reveal_all()`.
13081322
#[inline]
13091323
pub fn reveal_all() -> Self {
1310-
Self::new(List::empty(), Reveal::All)
1324+
Self::new(List::empty(), Reveal::All, hir::Constness::NotConst)
13111325
}
13121326

13131327
/// Construct a trait environment with the given set of predicates.
13141328
#[inline]
1315-
pub fn new(caller_bounds: &'tcx List<Predicate<'tcx>>, reveal: Reveal) -> Self {
1316-
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
1329+
pub fn new(
1330+
caller_bounds: &'tcx List<Predicate<'tcx>>,
1331+
reveal: Reveal,
1332+
constness: hir::Constness,
1333+
) -> Self {
1334+
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) }
13171335
}
13181336

13191337
pub fn with_user_facing(mut self) -> Self {
@@ -1335,13 +1353,17 @@ impl<'tcx> ParamEnv<'tcx> {
13351353
return self;
13361354
}
13371355

1338-
ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All)
1356+
ParamEnv::new(
1357+
tcx.normalize_opaque_types(self.caller_bounds()),
1358+
Reveal::All,
1359+
self.constness(),
1360+
)
13391361
}
13401362

13411363
/// Returns this same environment but with no caller bounds.
13421364
#[inline]
13431365
pub fn without_caller_bounds(self) -> Self {
1344-
Self::new(List::empty(), self.reveal())
1366+
Self::new(List::empty(), self.reveal(), self.constness())
13451367
}
13461368

13471369
/// Creates a suitable environment in which to perform trait

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
480480
type Lifted = ty::ParamEnv<'tcx>;
481481
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
482482
tcx.lift(self.caller_bounds())
483-
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal()))
483+
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
484484
}
485485
}
486486

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,17 @@ impl AutoTraitFinder<'tcx> {
370370
computed_preds.clone().chain(user_computed_preds.iter().cloned()),
371371
)
372372
.map(|o| o.predicate);
373-
new_env = ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal());
373+
new_env = ty::ParamEnv::new(
374+
tcx.mk_predicates(normalized_preds),
375+
param_env.reveal(),
376+
param_env.constness(),
377+
);
374378
}
375379

376380
let final_user_env = ty::ParamEnv::new(
377381
tcx.mk_predicates(user_computed_preds.into_iter()),
378382
user_env.reveal(),
383+
user_env.constness(),
379384
);
380385
debug!(
381386
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,11 @@ pub fn normalize_param_env_or_error<'tcx>(
307307

308308
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
309309

310-
let elaborated_env =
311-
ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal());
310+
let elaborated_env = ty::ParamEnv::new(
311+
tcx.intern_predicates(&predicates),
312+
unnormalized_env.reveal(),
313+
unnormalized_env.constness(),
314+
);
312315

313316
// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
314317
// normalization expects its param-env to be already normalized, which means we have
@@ -360,8 +363,11 @@ pub fn normalize_param_env_or_error<'tcx>(
360363
// predicates here anyway. Keeping them here anyway because it seems safer.
361364
let outlives_env: Vec<_> =
362365
non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
363-
let outlives_env =
364-
ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal());
366+
let outlives_env = ty::ParamEnv::new(
367+
tcx.intern_predicates(&outlives_env),
368+
unnormalized_env.reveal(),
369+
unnormalized_env.constness(),
370+
);
365371
let outlives_predicates = match do_normalize_predicates(
366372
tcx,
367373
region_context,
@@ -381,7 +387,11 @@ pub fn normalize_param_env_or_error<'tcx>(
381387
let mut predicates = non_outlives_predicates;
382388
predicates.extend(outlives_predicates);
383389
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
384-
ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal())
390+
ty::ParamEnv::new(
391+
tcx.intern_predicates(&predicates),
392+
unnormalized_env.reveal(),
393+
unnormalized_env.constness(),
394+
)
385395
}
386396

387397
pub fn fully_normalize<'a, 'tcx, T>(

compiler/rustc_trait_selection/src/traits/object_safety.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,11 @@ fn receiver_is_dispatchable<'tcx>(
698698
.chain(array::IntoIter::new([unsize_predicate, trait_predicate]))
699699
.collect();
700700

701-
ty::ParamEnv::new(tcx.intern_predicates(&caller_bounds), param_env.reveal())
701+
ty::ParamEnv::new(
702+
tcx.intern_predicates(&caller_bounds),
703+
param_env.reveal(),
704+
param_env.constness(),
705+
)
702706
};
703707

704708
// Receiver: DispatchFromDyn<Receiver[Self => U]>

compiler/rustc_ty_utils/src/ty.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,16 +285,33 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
285285
// issue #89334
286286
predicates = tcx.expose_default_const_substs(predicates);
287287

288-
let unnormalized_env =
289-
ty::ParamEnv::new(tcx.intern_predicates(&predicates), traits::Reveal::UserFacing);
290-
291-
debug!("unnormalized_env caller bounds: {:?}", unnormalized_env.caller_bounds());
292-
let body_id = def_id
293-
.as_local()
294-
.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
295-
.map_or(hir::CRATE_HIR_ID, |id| {
296-
tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id)
297-
});
288+
let local_did = def_id.as_local();
289+
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
290+
291+
let constness = match hir_id {
292+
Some(hir_id) => match tcx.hir().opt_body_owner_kind(hir_id) {
293+
Err(hir::Node::Item(&hir::Item {
294+
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
295+
..
296+
})) => constness,
297+
Err(_) => hir::Constness::NotConst,
298+
Ok(_) => match tcx.hir().body_const_context(local_did.unwrap()) {
299+
Some(_) => hir::Constness::Const,
300+
None => hir::Constness::NotConst,
301+
},
302+
},
303+
None => hir::Constness::NotConst,
304+
};
305+
306+
let unnormalized_env = ty::ParamEnv::new(
307+
tcx.intern_predicates(&predicates),
308+
traits::Reveal::UserFacing,
309+
constness,
310+
);
311+
312+
let body_id = hir_id.map_or(hir::CRATE_HIR_ID, |id| {
313+
tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id)
314+
});
298315
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
299316
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
300317
}

compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,11 @@ fn compare_predicate_entailment<'tcx>(
208208
// The key step here is to update the caller_bounds's predicates to be
209209
// the new hybrid bounds we computed.
210210
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_hir_id);
211-
let param_env =
212-
ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing);
211+
let param_env = ty::ParamEnv::new(
212+
tcx.intern_predicates(&hybrid_preds.predicates),
213+
Reveal::UserFacing,
214+
hir::Constness::NotConst,
215+
);
213216
let param_env =
214217
traits::normalize_param_env_or_error(tcx, impl_m.def_id, param_env, normalize_cause);
215218

@@ -1183,8 +1186,11 @@ fn compare_type_predicate_entailment<'tcx>(
11831186
debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds);
11841187

11851188
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
1186-
let param_env =
1187-
ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing);
1189+
let param_env = ty::ParamEnv::new(
1190+
tcx.intern_predicates(&hybrid_preds.predicates),
1191+
Reveal::UserFacing,
1192+
hir::Constness::NotConst,
1193+
);
11881194
let param_env = traits::normalize_param_env_or_error(
11891195
tcx,
11901196
impl_ty.def_id,
@@ -1369,7 +1375,11 @@ pub fn check_type_bounds<'tcx>(
13691375
.to_predicate(tcx),
13701376
),
13711377
};
1372-
ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing)
1378+
ty::ParamEnv::new(
1379+
tcx.intern_predicates(&predicates),
1380+
Reveal::UserFacing,
1381+
param_env.constness(),
1382+
)
13731383
};
13741384
debug!(?normalize_param_env);
13751385

0 commit comments

Comments
 (0)