1
Fork 0

Auto merge of #132027 - RalfJung:lang-feature-bool-fields, r=nnethercote

nightly feature tracking: get rid of the per-feature bool fields

The `struct Features` that tracks which features are enabled has a ton of public `bool`-typed fields that are basically caching the result of looking up the corresponding feature in `enabled_lang_features`. Having public fields with an invariant is not great, so at least they should be made private. However, it turns out caching these lookups is actually [not worth it](https://github.com/rust-lang/rust/pull/131321#issuecomment-2402068336), so this PR just entirely gets rid of these fields. (The alternative would be to make them private and have a method for each of them to expose them in a read-only way. Most of the diff of this PR would be the same in that case.)

r? `@nnethercote`
This commit is contained in:
bors 2024-10-23 12:16:41 +00:00
commit be01dabfef
111 changed files with 324 additions and 385 deletions

View file

@ -3026,7 +3026,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
obligation: &PredicateObligation<'tcx>,
span: Span,
) -> Result<Diag<'a>, ErrorGuaranteed> {
if !self.tcx.features().generic_const_exprs {
if !self.tcx.features().generic_const_exprs() {
let guar = self
.dcx()
.struct_span_err(span, "constant expression depends on a generic parameter")

View file

@ -3044,7 +3044,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if local {
err.note("all local variables must have a statically known size");
}
if !tcx.features().unsized_locals {
if !tcx.features().unsized_locals() {
err.help("unsized locals are gated as an unstable feature");
}
}
@ -3125,7 +3125,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
err.note("all function arguments must have a statically known size");
}
if tcx.sess.opts.unstable_features.is_nightly_build()
&& !tcx.features().unsized_fn_params
&& !tcx.features().unsized_fn_params()
{
err.help("unsized fn params are gated as an unstable feature");
}
@ -4510,7 +4510,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
) {
// Don't suggest if RTN is active -- we should prefer a where-clause bound instead.
if self.tcx.features().return_type_notation {
if self.tcx.features().return_type_notation() {
return;
}

View file

@ -40,7 +40,7 @@ pub fn is_const_evaluatable<'tcx>(
ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
};
if tcx.features().generic_const_exprs {
if tcx.features().generic_const_exprs() {
let ct = tcx.expand_abstract_consts(unexpanded_ct);
let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() {

View file

@ -254,7 +254,7 @@ fn super_predicates_have_non_lifetime_binders(
trait_def_id: DefId,
) -> SmallVec<[Span; 1]> {
// If non_lifetime_binders is disabled, then exit early
if !tcx.features().non_lifetime_binders {
if !tcx.features().non_lifetime_binders() {
return SmallVec::new();
}
tcx.explicit_super_predicates_of(trait_def_id)
@ -327,7 +327,7 @@ pub fn dyn_compatibility_violations_for_assoc_item(
.collect(),
// Associated types can only be dyn-compatible if they have `Self: Sized` bounds.
ty::AssocKind::Type => {
if !tcx.features().generic_associated_types_extended
if !tcx.features().generic_associated_types_extended()
&& !tcx.generics_of(item.def_id).is_own_empty()
&& !item.is_impl_trait_in_trait()
{

View file

@ -598,7 +598,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
ty::PredicateKind::ConstEquate(c1, c2) => {
let tcx = self.selcx.tcx();
assert!(
tcx.features().generic_const_exprs,
tcx.features().generic_const_exprs(),
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
);
// FIXME: we probably should only try to unify abstract constants

View file

@ -346,7 +346,7 @@ pub fn normalize_param_env_or_error<'tcx>(
let mut predicates: Vec<_> = util::elaborate(
tcx,
unnormalized_env.caller_bounds().into_iter().map(|predicate| {
if tcx.features().generic_const_exprs {
if tcx.features().generic_const_exprs() {
return predicate;
}

View file

@ -402,7 +402,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
#[instrument(skip(self), level = "debug")]
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
let tcx = self.selcx.tcx();
if tcx.features().generic_const_exprs
if tcx.features().generic_const_exprs()
|| !needs_normalization(&constant, self.param_env.reveal())
{
constant

View file

@ -189,7 +189,7 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
ProjectAndUnifyResult::Holds(obligations)
if old_universe != new_universe
&& selcx.tcx().features().generic_associated_types_extended =>
&& selcx.tcx().features().generic_associated_types_extended() =>
{
// If the `generic_associated_types_extended` feature is active, then we ignore any
// obligations references lifetimes from any universe greater than or equal to the

View file

@ -876,7 +876,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
if let Some(principal) = data.principal() {
if !self.infcx.tcx.features().dyn_compatible_for_dispatch {
if !self.infcx.tcx.features().dyn_compatible_for_dispatch() {
principal.with_self_ty(self.tcx(), self_ty)
} else if self.tcx().is_dyn_compatible(principal.def_id()) {
principal.with_self_ty(self.tcx(), self_ty)
@ -936,7 +936,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
let tcx = self.tcx();
if tcx.features().trait_upcasting {
if tcx.features().trait_upcasting() {
return None;
}

View file

@ -402,7 +402,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut assume = predicate.trait_ref.args.const_at(2);
// FIXME(min_generic_const_exprs): We should shallowly normalize this.
if self.tcx().features().generic_const_exprs {
if self.tcx().features().generic_const_exprs() {
assume = assume.normalize_internal(self.tcx(), obligation.param_env);
}
let Some(assume) =
@ -626,7 +626,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
for assoc_type in assoc_types {
let defs: &ty::Generics = tcx.generics_of(assoc_type);
if !defs.own_params.is_empty() && !tcx.features().generic_associated_types_extended {
if !defs.own_params.is_empty() && !tcx.features().generic_associated_types_extended() {
tcx.dcx().span_delayed_bug(
obligation.cause.span,
"GATs in trait object shouldn't have been considered",

View file

@ -865,7 +865,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::PredicateKind::ConstEquate(c1, c2) => {
let tcx = self.tcx();
assert!(
tcx.features().generic_const_exprs,
tcx.features().generic_const_exprs(),
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
);
@ -2195,7 +2195,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
match self.tcx().coroutine_movability(coroutine_def_id) {
hir::Movability::Static => None,
hir::Movability::Movable => {
if self.tcx().features().coroutine_clone {
if self.tcx().features().coroutine_clone() {
let resolved_upvars =
self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
let resolved_witness =

View file

@ -136,7 +136,7 @@ pub fn translate_args_with_cause<'tcx>(
}
pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool {
tcx.features().specialization || tcx.features().min_specialization
tcx.features().specialization() || tcx.features().min_specialization()
}
/// Is `impl1` a specialization of `impl2`?

View file

@ -82,7 +82,7 @@ impl<'tcx> At<'_, 'tcx> {
}
Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
} else if self.infcx.tcx.features().generic_const_exprs {
} else if self.infcx.tcx.features().generic_const_exprs() {
Ok(ct.normalize_internal(self.infcx.tcx, self.param_env))
} else {
Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))

View file

@ -836,7 +836,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
// obligations that don't refer to Self and
// checking those
let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch;
let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch();
if !defer_to_coercion {
if let Some(principal) = data.principal_def_id() {