From ad3991d30382676f987a38243b3097d880b9033a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 9 Oct 2024 09:01:57 +0200 Subject: [PATCH 1/5] nightly feature tracking: get rid of the per-feature bool fields --- compiler/rustc_ast_lowering/src/asm.rs | 6 +- compiler/rustc_ast_lowering/src/expr.rs | 8 +- compiler/rustc_ast_lowering/src/item.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 12 +- compiler/rustc_ast_lowering/src/path.rs | 4 +- .../rustc_ast_passes/src/ast_validation.rs | 22 +-- compiler/rustc_ast_passes/src/feature_gate.rs | 18 +-- compiler/rustc_attr/src/builtin.rs | 10 +- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_builtin_macros/src/assert.rs | 2 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 10 +- .../rustc_codegen_ssa/src/target_features.rs | 42 +++--- .../src/check_consts/check.rs | 4 +- .../rustc_const_eval/src/check_consts/mod.rs | 2 +- .../src/check_consts/post_drop_elaboration.rs | 2 +- compiler/rustc_expand/src/config.rs | 8 +- compiler/rustc_expand/src/expand.rs | 4 +- compiler/rustc_expand/src/mbe/quoted.rs | 4 +- compiler/rustc_feature/src/builtin_attrs.rs | 4 +- compiler/rustc_feature/src/unstable.rs | 138 +++++++----------- compiler/rustc_hir_analysis/src/bounds.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 4 +- .../rustc_hir_analysis/src/check/region.rs | 8 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 10 +- .../src/coherence/inherent_impls.rs | 4 +- .../rustc_hir_analysis/src/coherence/mod.rs | 6 +- compiler/rustc_hir_analysis/src/collect.rs | 4 +- .../src/collect/generics_of.rs | 2 +- .../src/collect/predicates_of.rs | 4 +- .../src/collect/resolve_bound_vars.rs | 4 +- .../rustc_hir_analysis/src/collect/type_of.rs | 4 +- .../src/hir_ty_lowering/bounds.rs | 2 +- .../src/hir_ty_lowering/errors.rs | 4 +- .../src/hir_ty_lowering/mod.rs | 2 +- .../rustc_hir_analysis/src/impl_wf_check.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 6 +- .../rustc_hir_analysis/src/outlives/mod.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 2 +- compiler/rustc_hir_typeck/src/coercion.rs | 14 +- compiler/rustc_hir_typeck/src/expr.rs | 10 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- .../rustc_hir_typeck/src/gather_locals.rs | 4 +- compiler/rustc_hir_typeck/src/lib.rs | 2 +- .../rustc_hir_typeck/src/method/confirm.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 10 +- compiler/rustc_hir_typeck/src/pat.rs | 16 +- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- .../rustc_incremental/src/assert_dep_graph.rs | 2 +- .../src/persist/dirty_clean.rs | 2 +- compiler/rustc_lint/src/async_fn_in_trait.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 6 +- compiler/rustc_lint/src/if_let_rescope.rs | 2 +- .../rustc_lint/src/impl_trait_overcaptures.rs | 4 +- .../rustc_lint/src/tail_expr_drop_order.rs | 2 +- .../rustc_metadata/src/dependency_format.rs | 2 +- compiler/rustc_metadata/src/native_libs.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 +- .../rustc_middle/src/mir/interpret/queries.rs | 2 +- .../src/traits/specialization_graph.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 8 +- .../src/build/expr/as_operand.rs | 2 +- .../rustc_mir_build/src/build/matches/test.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- .../src/thir/pattern/check_match.rs | 2 +- compiler/rustc_mir_transform/src/coroutine.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 2 +- compiler/rustc_passes/src/abi_test.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_passes/src/check_const.rs | 2 +- compiler/rustc_passes/src/layout_test.rs | 2 +- compiler/rustc_passes/src/lib_features.rs | 2 +- compiler/rustc_passes/src/stability.rs | 10 +- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +- .../src/ich/impls_syntax.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 4 +- compiler/rustc_resolve/src/late.rs | 10 +- .../rustc_resolve/src/late/diagnostics.rs | 6 +- compiler/rustc_resolve/src/macros.rs | 4 +- compiler/rustc_symbol_mangling/src/test.rs | 2 +- .../traits/fulfillment_errors.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 6 +- .../src/traits/const_evaluatable.rs | 2 +- .../src/traits/dyn_compatibility.rs | 4 +- .../src/traits/fulfill.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/normalize.rs | 2 +- .../src/traits/project.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 4 +- .../src/traits/select/confirmation.rs | 4 +- .../src/traits/select/mod.rs | 4 +- .../src/traits/specialize/mod.rs | 2 +- .../src/traits/structural_normalize.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 2 +- compiler/rustc_ty_utils/src/consts.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/types.rs | 4 +- .../passes/check_doc_test_visibility.rs | 2 +- .../passes/collect_intra_doc_links.rs | 2 +- .../clippy/clippy_lints/src/empty_enum.rs | 2 +- .../src/matches/match_same_arms.rs | 2 +- .../src/matches/redundant_guards.rs | 2 +- 108 files changed, 299 insertions(+), 331 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 88cdb2ec36397..6585a7de24591 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -49,7 +49,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | asm::InlineAsmArch::RiscV64 | asm::InlineAsmArch::LoongArch64 ); - if !is_stable && !self.tcx.features().asm_experimental_arch { + if !is_stable && !self.tcx.features().asm_experimental_arch() { feature_err( &self.tcx.sess, sym::asm_experimental_arch, @@ -65,7 +65,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { { self.dcx().emit_err(AttSyntaxOnlyX86 { span: sp }); } - if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind { + if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind() { feature_err( &self.tcx.sess, sym::asm_unwind, @@ -237,7 +237,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } InlineAsmOperand::Label { block } => { - if !self.tcx.features().asm_goto { + if !self.tcx.features().asm_goto() { feature_err( sess, sym::asm_goto, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index ae1e1b3f8a21d..a1a16d0ca2632 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -575,7 +575,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } else { // Either `body.is_none()` or `is_never_pattern` here. if !is_never_pattern { - if self.tcx.features().never_patterns { + if self.tcx.features().never_patterns() { // If the feature is off we already emitted the error after parsing. let suggestion = span.shrink_to_hi(); self.dcx().emit_err(MatchArmWithNoBody { span, suggestion }); @@ -717,7 +717,7 @@ impl<'hir> LoweringContext<'_, 'hir> { outer_hir_id: HirId, inner_hir_id: HirId, ) { - if self.tcx.features().async_fn_track_caller + if self.tcx.features().async_fn_track_caller() && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)) { @@ -1572,7 +1572,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); } Some(hir::CoroutineKind::Coroutine(_)) => { - if !self.tcx.features().coroutines { + if !self.tcx.features().coroutines() { rustc_session::parse::feature_err( &self.tcx.sess, sym::coroutines, @@ -1584,7 +1584,7 @@ impl<'hir> LoweringContext<'_, 'hir> { false } None => { - if !self.tcx.features().coroutines { + if !self.tcx.features().coroutines() { rustc_session::parse::feature_err( &self.tcx.sess, sym::coroutines, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7416a1e39eb53..c43106c6e5f63 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1512,7 +1512,7 @@ impl<'hir> LoweringContext<'_, 'hir> { continue; } let is_param = *is_param.get_or_insert_with(compute_is_param); - if !is_param && !self.tcx.features().more_maybe_bounds { + if !is_param && !self.tcx.features().more_maybe_bounds() { self.tcx .sess .create_feature_err( @@ -1530,7 +1530,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let host_param_parts = if let Const::Yes(span) = constness // if this comes from implementing a `const` trait, we must force constness to be appended // to the impl item, no matter whether effects is enabled. - && (self.tcx.features().effects || force_append_constness) + && (self.tcx.features().effects() || force_append_constness) { let span = self.lower_span(span); let param_node_id = self.next_node_id(); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 28523bcb3bf7b..7cd0cd1ebcdc4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -193,7 +193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { impl_trait_defs: Vec::new(), impl_trait_bounds: Vec::new(), allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(), - allow_gen_future: if tcx.features().async_fn_track_caller { + allow_gen_future: if tcx.features().async_fn_track_caller() { [sym::gen_future, sym::closure_track_caller].into() } else { [sym::gen_future].into() @@ -1035,7 +1035,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: data.inputs_span, }) }; - if !self.tcx.features().return_type_notation + if !self.tcx.features().return_type_notation() && self.tcx.sess.is_nightly_build() { add_feature_diagnostics( @@ -1160,7 +1160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)), ast::GenericArg::Type(ty) => { match &ty.kind { - TyKind::Infer if self.tcx.features().generic_arg_infer => { + TyKind::Infer if self.tcx.features().generic_arg_infer() => { return GenericArg::Infer(hir::InferArg { hir_id: self.lower_node_id(ty.id), span: self.lower_span(ty.span), @@ -1500,7 +1500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // is enabled. We don't check the span of the edition, since this is done // on a per-opaque basis to account for nested opaques. let always_capture_in_scope = match origin { - _ if self.tcx.features().lifetime_capture_rules_2024 => true, + _ if self.tcx.features().lifetime_capture_rules_2024() => true, hir::OpaqueTyOrigin::TyAlias { .. } => true, hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => in_trait_or_impl.is_some(), hir::OpaqueTyOrigin::AsyncFn { .. } => { @@ -1519,7 +1519,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Feature gate for RPITIT + use<..> match origin { rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => { - if !self.tcx.features().precise_capturing_in_traits + if !self.tcx.features().precise_capturing_in_traits() && let Some(span) = bounds.iter().find_map(|bound| match *bound { ast::GenericBound::Use(_, span) => Some(span), _ => None, @@ -2270,7 +2270,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen<'hir> { match c.value.kind { ExprKind::Underscore => { - if self.tcx.features().generic_arg_infer { + if self.tcx.features().generic_arg_infer() { hir::ArrayLen::Infer(hir::InferArg { hir_id: self.lower_node_id(c.id), span: self.lower_span(c.value.span), diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index e60488fdc8c74..258655de486f9 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -268,7 +268,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: data.inputs_span, }) }; - if !self.tcx.features().return_type_notation + if !self.tcx.features().return_type_notation() && self.tcx.sess.is_nightly_build() { add_feature_diagnostics( @@ -496,7 +496,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^ // ``` FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => { - if self.tcx.features().impl_trait_in_fn_trait_return { + if self.tcx.features().impl_trait_in_fn_trait_return() { self.lower_ty(ty, itctx) } else { self.lower_ty( diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 20a4f2120dcdf..bf6ebfb160bc4 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -295,7 +295,8 @@ impl<'a> AstValidator<'a> { return; }; - let make_impl_const_sugg = if self.features.const_trait_impl + let const_trait_impl = self.features.const_trait_impl(); + let make_impl_const_sugg = if const_trait_impl && let TraitOrTraitImpl::TraitImpl { constness: Const::No, polarity: ImplPolarity::Positive, @@ -308,13 +309,12 @@ impl<'a> AstValidator<'a> { None }; - let make_trait_const_sugg = if self.features.const_trait_impl - && let TraitOrTraitImpl::Trait { span, constness: None } = parent - { - Some(span.shrink_to_lo()) - } else { - None - }; + let make_trait_const_sugg = + if const_trait_impl && let TraitOrTraitImpl::Trait { span, constness: None } = parent { + Some(span.shrink_to_lo()) + } else { + None + }; let parent_constness = parent.constness(); self.dcx().emit_err(errors::TraitFnConst { @@ -1145,7 +1145,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } self.check_type_no_bounds(bounds, "this context"); - if self.features.lazy_type_alias { + if self.features.lazy_type_alias() { if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) { self.dcx().emit_err(err); } @@ -1286,7 +1286,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { GenericBound::Trait(trait_ref) => { match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) { (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) - if !self.features.more_maybe_bounds => + if !self.features.more_maybe_bounds() => { self.sess .create_feature_err( @@ -1299,7 +1299,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .emit(); } (BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) - if !self.features.more_maybe_bounds => + if !self.features.more_maybe_bounds() => { self.sess .create_feature_err( diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 94fcfabc32cad..348a602fd59d1 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -15,13 +15,13 @@ use crate::errors; /// The common case. macro_rules! gate { ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{ - if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) { + if !$visitor.features.$feature() && !$span.allows_unstable(sym::$feature) { #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable feature_err(&$visitor.sess, sym::$feature, $span, $explain).emit(); } }}; ($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{ - if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) { + if !$visitor.features.$feature() && !$span.allows_unstable(sym::$feature) { // FIXME: make this translatable #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] @@ -43,7 +43,7 @@ macro_rules! gate_alt { /// The case involving a multispan. macro_rules! gate_multi { ($visitor:expr, $feature:ident, $spans:expr, $explain:expr) => {{ - if !$visitor.features.$feature { + if !$visitor.features.$feature() { let spans: Vec<_> = $spans.filter(|span| !span.allows_unstable(sym::$feature)).collect(); if !spans.is_empty() { @@ -56,7 +56,7 @@ macro_rules! gate_multi { /// The legacy case. macro_rules! gate_legacy { ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{ - if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) { + if !$visitor.features.$feature() && !$span.allows_unstable(sym::$feature) { feature_warn(&$visitor.sess, sym::$feature, $span, $explain); } }}; @@ -150,7 +150,7 @@ impl<'a> PostExpansionVisitor<'a> { // FIXME(non_lifetime_binders): Const bound params are pretty broken. // Let's keep users from using this feature accidentally. - if self.features.non_lifetime_binders { + if self.features.non_lifetime_binders() { let const_param_spans: Vec<_> = params .iter() .filter_map(|param| match param.kind { @@ -210,7 +210,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } // Emit errors for non-staged-api crates. - if !self.features.staged_api { + if !self.features.staged_api() { if attr.has_name(sym::unstable) || attr.has_name(sym::stable) || attr.has_name(sym::rustc_const_unstable) @@ -470,7 +470,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { // Limit `min_specialization` to only specializing functions. gate_alt!( &self, - self.features.specialization || (is_fn && self.features.min_specialization), + self.features.specialization() || (is_fn && self.features.min_specialization()), sym::specialization, i.span, "specialization is unstable" @@ -548,7 +548,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); - if !visitor.features.never_patterns { + if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { for &span in spans { if span.allows_unstable(sym::never_patterns) { @@ -572,7 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { } } - if !visitor.features.negative_bounds { + if !visitor.features.negative_bounds() { for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() { sess.dcx().emit_err(errors::NegativeBoundUnsupported { span }); } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index bbb1749768449..e412417a9e95f 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -622,7 +622,7 @@ pub fn eval_condition( &(( if *b { kw::True } else { kw::False }, sym::cfg_boolean_literals, - |features: &Features| features.cfg_boolean_literals, + |features: &Features| features.cfg_boolean_literals(), )), cfg.span(), sess, @@ -711,7 +711,7 @@ pub fn eval_condition( } sym::target => { if let Some(features) = features - && !features.cfg_target_compact + && !features.cfg_target_compact() { feature_err( sess, @@ -831,7 +831,7 @@ pub fn find_deprecation( attrs: &[Attribute], ) -> Option<(Deprecation, Span)> { let mut depr: Option<(Deprecation, Span)> = None; - let is_rustc = features.staged_api; + let is_rustc = features.staged_api(); 'outer: for attr in attrs { if !attr.has_name(sym::deprecated) { @@ -891,7 +891,7 @@ pub fn find_deprecation( } } sym::suggestion => { - if !features.deprecated_suggestion { + if !features.deprecated_suggestion() { sess.dcx().emit_err( session_diagnostics::DeprecatedItemSuggestion { span: mi.span, @@ -909,7 +909,7 @@ pub fn find_deprecation( sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { span: meta.span(), item: pprust::path_to_string(&mi.path), - expected: if features.deprecated_suggestion { + expected: if features.deprecated_suggestion() { &["since", "note", "suggestion"] } else { &["since", "note"] diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 7b60a632c3052..a544d88e8321e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1035,7 +1035,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn unsized_feature_enabled(&self) -> bool { let features = self.tcx().features(); - features.unsized_locals || features.unsized_fn_params + features.unsized_locals() || features.unsized_fn_params() } /// Equate the inferred type and the annotated type for user type annotations diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 714493509859a..599b180f8793d 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -69,7 +69,7 @@ pub(crate) fn expand_assert<'cx>( // If `generic_assert` is enabled, generates rich captured outputs // // FIXME(c410-f3r) See https://github.com/rust-lang/rust/issues/96949 - else if cx.ecfg.features.generic_assert { + else if cx.ecfg.features.generic_assert() { context::Context::new(cx, call_site_span).build(cond_expr, panic_path()) } // If `generic_assert` is not enabled, only outputs a literal "assertion failed: ..." diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index d536419ab3c20..a5bd3adbcddc9 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -137,7 +137,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let inner = attr.meta_item_list(); match inner.as_deref() { Some([item]) if item.has_name(sym::linker) => { - if !tcx.features().used_with_arg { + if !tcx.features().used_with_arg() { feature_err( &tcx.sess, sym::used_with_arg, @@ -149,7 +149,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER; } Some([item]) if item.has_name(sym::compiler) => { - if !tcx.features().used_with_arg { + if !tcx.features().used_with_arg() { feature_err( &tcx.sess, sym::used_with_arg, @@ -213,7 +213,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { .emit(); } if is_closure - && !tcx.features().closure_track_caller + && !tcx.features().closure_track_caller() && !attr.span.allows_unstable(sym::closure_track_caller) { feature_err( @@ -268,7 +268,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // // This exception needs to be kept in sync with allowing // `#[target_feature]` on `main` and `start`. - } else if !tcx.features().target_feature_11 { + } else if !tcx.features().target_feature_11() { feature_err( &tcx.sess, sym::target_feature_11, @@ -584,7 +584,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // its parent function, which effectively inherits the features anyway. Boxing this closure // would result in this closure being compiled without the inherited target features, but this // is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute. - if tcx.features().target_feature_11 + if tcx.features().target_feature_11() && tcx.is_closure_like(did.to_def_id()) && codegen_fn_attrs.inline != InlineAttr::Always { diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index dfe8fd616e4a2..d99307106092f 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -63,27 +63,27 @@ pub(crate) fn from_target_feature( // Only allow features whose feature gates have been enabled. let allowed = match feature_gate.as_ref().copied() { - Some(sym::arm_target_feature) => rust_features.arm_target_feature, - Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature, - Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature, - Some(sym::mips_target_feature) => rust_features.mips_target_feature, - Some(sym::riscv_target_feature) => rust_features.riscv_target_feature, - Some(sym::avx512_target_feature) => rust_features.avx512_target_feature, - Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature, - Some(sym::tbm_target_feature) => rust_features.tbm_target_feature, - Some(sym::wasm_target_feature) => rust_features.wasm_target_feature, - Some(sym::rtm_target_feature) => rust_features.rtm_target_feature, - Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature, - Some(sym::bpf_target_feature) => rust_features.bpf_target_feature, - Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature, - Some(sym::csky_target_feature) => rust_features.csky_target_feature, - Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature, - Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature, - Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature, - Some(sym::sha512_sm_x86) => rust_features.sha512_sm_x86, - Some(sym::x86_amx_intrinsics) => rust_features.x86_amx_intrinsics, - Some(sym::xop_target_feature) => rust_features.xop_target_feature, - Some(sym::s390x_target_feature) => rust_features.s390x_target_feature, + Some(sym::arm_target_feature) => rust_features.arm_target_feature(), + Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature(), + Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature(), + Some(sym::mips_target_feature) => rust_features.mips_target_feature(), + Some(sym::riscv_target_feature) => rust_features.riscv_target_feature(), + Some(sym::avx512_target_feature) => rust_features.avx512_target_feature(), + Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature(), + Some(sym::tbm_target_feature) => rust_features.tbm_target_feature(), + Some(sym::wasm_target_feature) => rust_features.wasm_target_feature(), + Some(sym::rtm_target_feature) => rust_features.rtm_target_feature(), + Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature(), + Some(sym::bpf_target_feature) => rust_features.bpf_target_feature(), + Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature(), + Some(sym::csky_target_feature) => rust_features.csky_target_feature(), + Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature(), + Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature(), + Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature(), + Some(sym::sha512_sm_x86) => rust_features.sha512_sm_x86(), + Some(sym::x86_amx_intrinsics) => rust_features.x86_amx_intrinsics(), + Some(sym::xop_target_feature) => rust_features.xop_target_feature(), + Some(sym::s390x_target_feature) => rust_features.s390x_target_feature(), Some(name) => bug!("unknown target feature gate {}", name), None => true, }; diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 73344508a9d84..288798bf0c27f 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -611,7 +611,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // the trait into the concrete method, and uses that for const stability // checks. // FIXME(effects) we might consider moving const stability checks to typeck as well. - if tcx.features().effects { + if tcx.features().effects() { is_trait = true; if let Ok(Some(instance)) = @@ -631,7 +631,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { args: fn_args, span: *fn_span, call_source, - feature: Some(if tcx.features().const_trait_impl { + feature: Some(if tcx.features().const_trait_impl() { sym::effects } else { sym::const_trait_impl diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 15ac4cedcc328..3720418d4f019 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -61,7 +61,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn is_const_stable_const_fn(&self) -> bool { self.const_kind == Some(hir::ConstContext::ConstFn) - && self.tcx.features().staged_api + && self.tcx.features().staged_api() && is_const_stable_const_fn(self.tcx, self.def_id().to_def_id()) } diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index f98234ce7f3c1..d04d7b273f032 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -24,7 +24,7 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool { ); } - ccx.tcx.features().const_precise_live_drops + ccx.tcx.features().const_precise_live_drops() } /// Look for live drops in a const context. diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index a6b7291ee8f4f..7546c830a0b38 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -88,7 +88,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - // If the enabled feature is stable, record it. if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { let since = Some(Symbol::intern(f.since)); - features.set_enabled_lang_feature(name, mi.span(), since, None); + features.set_enabled_lang_feature(name, mi.span(), since); continue; } @@ -103,7 +103,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - } // If the enabled feature is unstable, record it. - if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) { + if UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_some() { // When the ICE comes from core, alloc or std (approximation of the standard // library), there's a chance that the person hitting the ICE may be using // -Zbuild-std or similar with an untested target. The bug is probably in the @@ -114,7 +114,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - { sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed); } - features.set_enabled_lang_feature(name, mi.span(), None, Some(f)); + features.set_enabled_lang_feature(name, mi.span(), None); continue; } @@ -395,7 +395,7 @@ impl<'a> StripUnconfigured<'a> { /// If attributes are not allowed on expressions, emit an error for `attr` #[instrument(level = "trace", skip(self))] pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) { - if self.features.is_some_and(|features| !features.stmt_expr_attributes) + if self.features.is_some_and(|features| !features.stmt_expr_attributes()) && !attr.span.allows_unstable(sym::stmt_expr_attributes) { let mut err = feature_err( diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index a872b12e744c4..5ffafcaa54262 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -867,7 +867,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { | Annotatable::FieldDef(..) | Annotatable::Variant(..) => panic!("unexpected annotatable"), }; - if self.cx.ecfg.features.proc_macro_hygiene { + if self.cx.ecfg.features.proc_macro_hygiene() { return; } feature_err( @@ -905,7 +905,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - if !self.cx.ecfg.features.proc_macro_hygiene { + if !self.cx.ecfg.features.proc_macro_hygiene() { annotatable.visit_with(&mut GateProcMacroInput { sess: &self.cx.sess }); } } diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index e518b27e419fc..1345f06d5ac10 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -121,14 +121,14 @@ pub(super) fn parse( /// Asks for the `macro_metavar_expr` feature if it is not enabled fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, span: Span) { - if !features.macro_metavar_expr { + if !features.macro_metavar_expr() { let msg = "meta-variable expressions are unstable"; feature_err(sess, sym::macro_metavar_expr, span, msg).emit(); } } fn maybe_emit_macro_metavar_expr_concat_feature(features: &Features, sess: &Session, span: Span) { - if !features.macro_metavar_expr_concat { + if !features.macro_metavar_expr_concat() { let msg = "the `concat` meta-variable expression is unstable"; feature_err(sess, sym::macro_metavar_expr_concat, span, msg).emit(); } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 477760a459757..5ba4491e97f5c 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -14,7 +14,7 @@ type GateFn = fn(&Features) -> bool; macro_rules! cfg_fn { ($field: ident) => { - (|features| features.$field) as GateFn + Features::$field as GateFn }; } @@ -1193,7 +1193,7 @@ pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> pub fn is_stable_diagnostic_attribute(sym: Symbol, features: &Features) -> bool { match sym { sym::on_unimplemented => true, - sym::do_not_recommend => features.do_not_recommend, + sym::do_not_recommend => features.do_not_recommend(), _ => false, } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 0606f2914c341..93e91c0984c71 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -8,7 +8,6 @@ use super::{Feature, to_nonzero}; pub struct UnstableFeature { pub feature: Feature, - set_enabled: fn(&mut Features), } #[derive(PartialEq)] @@ -30,6 +29,53 @@ macro_rules! status_to_enum { }; } +/// A set of features to be used by later passes. +/// +/// There are two ways to check if a language feature `foo` is enabled: +/// - Directly with the `foo` method, e.g. `if tcx.features().foo() { ... }`. +/// - With the `enabled` method, e.g. `if tcx.features.enabled(sym::foo) { ... }`. +/// +/// The former is preferred. `enabled` should only be used when the feature symbol is not a +/// constant, e.g. a parameter, or when the feature is a library feature. +#[derive(Clone, Default, Debug)] +pub struct Features { + /// `#![feature]` attrs for language features, for error reporting. + enabled_lang_features: Vec<(Symbol, Span, Option)>, + /// `#![feature]` attrs for non-language (library) features. + enabled_lib_features: Vec<(Symbol, Span)>, + /// `enabled_lang_features` + `enabled_lib_features`. + enabled_features: FxHashSet, +} + +impl Features { + pub fn set_enabled_lang_feature(&mut self, name: Symbol, span: Span, since: Option) { + self.enabled_lang_features.push((name, span, since)); + self.enabled_features.insert(name); + } + + pub fn set_enabled_lib_feature(&mut self, name: Symbol, span: Span) { + self.enabled_lib_features.push((name, span)); + self.enabled_features.insert(name); + } + + pub fn enabled_lang_features(&self) -> &Vec<(Symbol, Span, Option)> { + &self.enabled_lang_features + } + + pub fn enabled_lib_features(&self) -> &Vec<(Symbol, Span)> { + &self.enabled_lib_features + } + + pub fn enabled_features(&self) -> &FxHashSet { + &self.enabled_features + } + + /// Is the given feature enabled (via `#[feature(...)]`)? + pub fn enabled(&self, feature: Symbol) -> bool { + self.enabled_features.contains(&feature) + } +} + macro_rules! declare_features { ($( $(#[doc = $doc:tt])* ($status:ident, $feature:ident, $ver:expr, $issue:expr), @@ -43,97 +89,15 @@ macro_rules! declare_features { since: $ver, issue: to_nonzero($issue), }, - // Sets this feature's corresponding bool within `features`. - set_enabled: |features| features.$feature = true, }),+ ]; - const NUM_FEATURES: usize = UNSTABLE_FEATURES.len(); - - /// A set of features to be used by later passes. - #[derive(Clone, Default, Debug)] - pub struct Features { - /// `#![feature]` attrs for language features, for error reporting. - enabled_lang_features: Vec<(Symbol, Span, Option)>, - /// `#![feature]` attrs for non-language (library) features. - enabled_lib_features: Vec<(Symbol, Span)>, - /// `enabled_lang_features` + `enabled_lib_features`. - enabled_features: FxHashSet, - /// State of individual features (unstable lang features only). - /// This is `true` if and only if the corresponding feature is listed in `enabled_lang_features`. - $( - $(#[doc = $doc])* - pub $feature: bool - ),+ - } - impl Features { - pub fn set_enabled_lang_feature( - &mut self, - name: Symbol, - span: Span, - since: Option, - feature: Option<&UnstableFeature>, - ) { - self.enabled_lang_features.push((name, span, since)); - self.enabled_features.insert(name); - if let Some(feature) = feature { - assert_eq!(feature.feature.name, name); - (feature.set_enabled)(self); - } else { - // Ensure we don't skip a `set_enabled` call. - debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none()); - } - } - - pub fn set_enabled_lib_feature(&mut self, name: Symbol, span: Span) { - self.enabled_lib_features.push((name, span)); - self.enabled_features.insert(name); - // Ensure we don't skip a `set_enabled` call. - debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none()); - } - - /// This is intended for hashing the set of enabled language features. - /// - /// The expectation is that this produces much smaller code than other alternatives. - /// - /// Note that the total feature count is pretty small, so this is not a huge array. - #[inline] - pub fn all_lang_features(&self) -> [u8; NUM_FEATURES] { - [$(self.$feature as u8),+] - } - - pub fn enabled_lang_features(&self) -> &Vec<(Symbol, Span, Option)> { - &self.enabled_lang_features - } - - pub fn enabled_lib_features(&self) -> &Vec<(Symbol, Span)> { - &self.enabled_lib_features - } - - pub fn enabled_features(&self) -> &FxHashSet { - &self.enabled_features - } - - /// Is the given feature enabled (via `#[feature(...)]`)? - pub fn enabled(&self, feature: Symbol) -> bool { - let e = self.enabled_features.contains(&feature); - if cfg!(debug_assertions) { - // Ensure this matches `self.$feature`, if that exists. - let e2 = match feature { - $( sym::$feature => Some(self.$feature), )* - _ => None, - }; - if let Some(e2) = e2 { - assert_eq!( - e, e2, - "mismatch in feature state for `{feature}`: \ - `enabled_features` says {e} but `self.{feature}` says {e2}" - ); - } + $( + pub fn $feature(&self) -> bool { + self.enabled_features.contains(&sym::$feature) } - e - } + )* /// Some features are known to be incomplete and using them is likely to have /// unanticipated results, such as compiler crashes. We warn the user about these diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 9a2c38e51e2b8..77df0cb7ef902 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -72,7 +72,7 @@ impl<'tcx> Bounds<'tcx> { // FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else. // Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated // type bounds. - if !tcx.features().effects { + if !tcx.features().effects() { return; } match predicate_filter { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 2aeeb9450ce9b..97f3f1c8ef27b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1166,7 +1166,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) return; } - if adt.is_union() && !tcx.features().transparent_unions { + if adt.is_union() && !tcx.features().transparent_unions() { feature_err( &tcx.sess, sym::transparent_unions, @@ -1301,7 +1301,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { let repr_type_ty = def.repr().discr_type().to_ty(tcx); if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 { - if !tcx.features().repr128 { + if !tcx.features().repr128() { feature_err( &tcx.sess, sym::repr128, diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 1a5f465981287..312fb16c93aae 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -167,7 +167,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h } } if let Some(tail_expr) = blk.expr { - if visitor.tcx.features().shorter_tail_lifetimes + if visitor.tcx.features().shorter_tail_lifetimes() && blk.span.edition().at_least_rust_2024() { visitor.terminating_scopes.insert(tail_expr.hir_id.local_id); @@ -466,7 +466,8 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h hir::ExprKind::If(cond, then, Some(otherwise)) => { let expr_cx = visitor.cx; - let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope { + let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope() + { ScopeData::IfThenRescope } else { ScopeData::IfThen @@ -481,7 +482,8 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h hir::ExprKind::If(cond, then, None) => { let expr_cx = visitor.cx; - let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope { + let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope() + { ScopeData::IfThenRescope } else { ScopeData::IfThen diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f788456d4e9eb..3170c0ac9907d 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -110,7 +110,7 @@ where let mut wfcx = WfCheckingCtxt { ocx, span, body_def_id, param_env }; - if !tcx.features().trivial_bounds { + if !tcx.features().trivial_bounds() { wfcx.check_false_global_bounds() } f(&mut wfcx)?; @@ -921,7 +921,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), } => { let ty = tcx.type_of(param.def_id).instantiate_identity(); - if tcx.features().unsized_const_params { + if tcx.features().unsized_const_params() { enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { wfcx.register_bound( ObligationCause::new( @@ -935,7 +935,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ); Ok(()) }) - } else if tcx.features().adt_const_params { + } else if tcx.features().adt_const_params() { enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { wfcx.register_bound( ObligationCause::new( @@ -1698,9 +1698,9 @@ fn check_method_receiver<'tcx>( return Ok(()); } - let arbitrary_self_types_level = if tcx.features().arbitrary_self_types_pointers { + let arbitrary_self_types_level = if tcx.features().arbitrary_self_types_pointers() { Some(ArbitrarySelfTypesLevel::WithPointers) - } else if tcx.features().arbitrary_self_types { + } else if tcx.features().arbitrary_self_types() { Some(ArbitrarySelfTypesLevel::Basic) } else { None diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index dfb3c088afb0c..2afc2aec1baad 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -77,7 +77,7 @@ impl<'tcx> InherentCollect<'tcx> { return Ok(()); } - if self.tcx.features().rustc_attrs { + if self.tcx.features().rustc_attrs() { let items = self.tcx.associated_item_def_ids(impl_def_id); if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) { @@ -115,7 +115,7 @@ impl<'tcx> InherentCollect<'tcx> { ) -> Result<(), ErrorGuaranteed> { let items = self.tcx.associated_item_def_ids(impl_def_id); if !self.tcx.hir().rustc_coherence_is_core() { - if self.tcx.features().rustc_attrs { + if self.tcx.features().rustc_attrs() { for &impl_item in items { if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { let span = self.tcx.def_span(impl_def_id); diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index eea5a16ac6fd3..3aad4bafeb5ab 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -53,7 +53,7 @@ fn enforce_trait_manually_implementable( ) -> Result<(), ErrorGuaranteed> { let impl_header_span = tcx.def_span(impl_def_id); - if tcx.is_lang_item(trait_def_id, LangItem::Freeze) && !tcx.features().freeze_impls { + if tcx.is_lang_item(trait_def_id, LangItem::Freeze) && !tcx.features().freeze_impls() { feature_err( &tcx.sess, sym::freeze_impls, @@ -86,8 +86,8 @@ fn enforce_trait_manually_implementable( if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable = trait_def.specialization_kind { - if !tcx.features().specialization - && !tcx.features().min_specialization + if !tcx.features().specialization() + && !tcx.features().min_specialization() && !impl_header_span.allows_unstable(sym::specialization) && !impl_header_span.allows_unstable(sym::min_specialization) { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f63e2d40e3906..acc21d0994bf6 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1129,7 +1129,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { }; let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); - if paren_sugar && !tcx.features().unboxed_closures { + if paren_sugar && !tcx.features().unboxed_closures() { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); } @@ -1696,7 +1696,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( // Feature gate SIMD types in FFI, since I am not sure that the // ABIs are handled at all correctly. -huonw - if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi { + if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi() { let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| { if ty.is_simd() { let snip = tcx diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 14b6b17ed18a7..348b2260d2606 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -109,7 +109,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // We do not allow generic parameters in anon consts if we are inside // of a const parameter type, e.g. `struct Foo` is not allowed. None - } else if tcx.features().generic_const_exprs { + } else if tcx.features().generic_const_exprs() { let parent_node = tcx.parent_hir_node(hir_id); debug!(?parent_node); if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9bd8c70dcfe79..097a1fbc39360 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -308,7 +308,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } } - if tcx.features().generic_const_exprs { + if tcx.features().generic_const_exprs() { predicates.extend(const_evaluatable_predicates_of(tcx, def_id)); } @@ -524,7 +524,7 @@ pub(super) fn explicit_predicates_of<'tcx>( } } else { if matches!(def_kind, DefKind::AnonConst) - && tcx.features().generic_const_exprs + && tcx.features().generic_const_exprs() && let Some(defaulted_param_def_id) = tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id)) { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index cb7f0901c7e4a..95e07244a6b31 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1161,7 +1161,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { && let Some(param) = generics.params.iter().find(|p| p.def_id == param_id) && param.is_elided_lifetime() && !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async() - && !self.tcx.features().anonymous_lifetime_in_impl_trait + && !self.tcx.features().anonymous_lifetime_in_impl_trait() { let mut diag: rustc_errors::Diag<'_> = rustc_session::parse::feature_err( &self.tcx.sess, @@ -2239,7 +2239,7 @@ fn deny_non_region_late_bound( format!("late-bound {what} parameter not allowed on {where_}"), ); - let guar = diag.emit_unless(!tcx.features().non_lifetime_binders || !first); + let guar = diag.emit_unless(!tcx.features().non_lifetime_binders() || !first); first = false; *arg = ResolvedArg::Error(guar); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 470bcaeded167..84161ec764831 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -699,7 +699,7 @@ fn infer_placeholder_type<'tcx>( } fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) { - if !tcx.features().inherent_associated_types { + if !tcx.features().inherent_associated_types() { use rustc_session::parse::feature_err; use rustc_span::symbol::sym; feature_err( @@ -714,7 +714,7 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) { pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { use hir::intravisit::Visitor; - if tcx.features().lazy_type_alias { + if tcx.features().lazy_type_alias() { return true; } struct HasTait; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a8b2b9b7c0ac3..2b0e1350108f1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -88,7 +88,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; if seen_repeat { self.dcx().emit_err(err); - } else if !tcx.features().more_maybe_bounds { + } else if !tcx.features().more_maybe_bounds() { self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit(); }; } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 01768c89cca89..dd0f250a8e28b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -63,7 +63,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_segment: &'_ hir::PathSegment<'_>, is_impl: bool, ) { - if self.tcx().features().unboxed_closures { + if self.tcx().features().unboxed_closures() { return; } @@ -343,7 +343,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && let Some(hir_ty) = constraint.ty() && let ty = self.lower_ty(hir_ty) && (ty.is_enum() || ty.references_error()) - && tcx.features().associated_const_equality + && tcx.features().associated_const_equality() { Some(errors::AssocKindMismatchWrapInBracesSugg { lo: hir_ty.span.shrink_to_lo(), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index fe0cd572609fa..a73a2f925cd3e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1241,7 +1241,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle // errors (#108491) which mask the feature-gate error, needlessly confusing users // who use IATs by accident (#113265). - if !tcx.features().inherent_associated_types { + if !tcx.features().inherent_associated_types() { return Ok(None); } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 7f183324f0433..d9c70c3cee655 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -57,7 +57,7 @@ pub(crate) fn check_impl_wf( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let min_specialization = tcx.features().min_specialization; + let min_specialization = tcx.features().min_specialization(); let mut res = Ok(()); debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }); res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id)); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 71ee77f8f6172..3ad35163191e5 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -116,7 +116,7 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi return; } - let extended_abi_support = tcx.features().extended_varargs_abi_support; + let extended_abi_support = tcx.features().extended_varargs_abi_support(); let conventions = match (extended_abi_support, abi.supports_varargs()) { // User enabled additional ABI support for varargs and function ABI matches those ones. (true, true) => return, @@ -155,7 +155,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // FIXME(effects): remove once effects is implemented in old trait solver // or if the next solver is stabilized. - if tcx.features().effects && !tcx.next_trait_solver_globally() { + if tcx.features().effects() && !tcx.next_trait_solver_globally() { tcx.dcx().emit_err(errors::EffectsWithoutNextSolver); } @@ -172,7 +172,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); }); - if tcx.features().rustc_attrs { + if tcx.features().rustc_attrs() { tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx)); tcx.sess.time("variance_dumping", || variance::dump::variances(tcx)); collect::dump::opaque_hidden_types(tcx); diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index e3cdb1bf5f7d6..c43917649de2e 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -23,7 +23,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau let crate_map = tcx.inferred_outlives_crate(()); crate_map.predicates.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]) } - DefKind::AnonConst if tcx.features().generic_const_exprs => { + DefKind::AnonConst if tcx.features().generic_const_exprs() => { let id = tcx.local_def_id_to_hir_id(item_def_id); if tcx.hir().opt_const_param_default_param_def_id(id).is_some() { // In `generics_of` we set the generics' parent to be our parent's parent which means that diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 8fa6ab8503d08..f7306063c1603 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -721,7 +721,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { use rustc_middle::ty::cast::IntTy::*; if self.cast_ty.is_dyn_star() { - if fcx.tcx.features().dyn_star { + if fcx.tcx.features().dyn_star() { span_bug!(self.span, "should be handled by `coerce`"); } else { // Report "casting is invalid" rather than "non-primitive cast" diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 406d668e7a5bf..de80ccf790c1b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -223,11 +223,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::Ref(r_b, _, mutbl_b) => { return self.coerce_borrowed_pointer(a, b, r_b, mutbl_b); } - ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star => { + ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star() => { return self.coerce_dyn_star(a, b, predicates, region); } ty::Adt(pin, _) - if self.tcx.features().pin_ergonomics + if self.tcx.features().pin_ergonomics() && self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => { return self.coerce_pin(a, b); @@ -698,7 +698,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } if let Some((sub, sup)) = has_trait_upcasting_coercion - && !self.tcx().features().trait_upcasting + && !self.tcx().features().trait_upcasting() { // Renders better when we erase regions, since they're not really the point here. let (sub, sup) = self.tcx.erase_regions((sub, sup)); @@ -712,7 +712,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { err.emit(); } - if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion { + if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() { feature_err( &self.tcx.sess, sym::unsized_tuple_coercion, @@ -732,7 +732,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { predicates: &'tcx ty::List>, b_region: ty::Region<'tcx>, ) -> CoerceResult<'tcx> { - if !self.tcx.features().dyn_star { + if !self.tcx.features().dyn_star() { return Err(TypeError::Mismatch); } @@ -1695,7 +1695,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { blk_id, expression, ); - if !fcx.tcx.features().unsized_locals { + if !fcx.tcx.features().unsized_locals() { unsized_return = self.is_return_ty_definitely_unsized(fcx); } } @@ -1709,7 +1709,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { return_expr_id, expression, ); - if !fcx.tcx.features().unsized_locals { + if !fcx.tcx.features().unsized_locals() { unsized_return = self.is_return_ty_definitely_unsized(fcx); } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a1813782e2937..da231acbb0f64 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -735,7 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // be known if explicitly specified via turbofish). self.deferred_transmute_checks.borrow_mut().push((*from, to, expr.hir_id)); } - if !tcx.features().unsized_fn_params { + if !tcx.features().unsized_fn_params() { // We want to remove some Sized bounds from std functions, // but don't want to expose the removal to stable Rust. // i.e., we don't want to allow @@ -1996,7 +1996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(base_expr) = base_expr { // FIXME: We are currently creating two branches here in order to maintain // consistency. But they should be merged as much as possible. - let fru_tys = if self.tcx.features().type_changing_struct_update { + let fru_tys = if self.tcx.features().type_changing_struct_update() { if adt.is_struct() { // Make some fresh generic parameters for our ADT type. let fresh_args = self.fresh_args_for_item(base_expr.span, adt.did()); @@ -3552,7 +3552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (ident, _def_scope) = self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block); - if !self.tcx.features().offset_of_enum { + if !self.tcx.features().offset_of_enum() { rustc_session::parse::feature_err( &self.tcx.sess, sym::offset_of_enum, @@ -3642,7 +3642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let field_ty = self.field_ty(expr.span, field, args); - if self.tcx.features().offset_of_slice { + if self.tcx.features().offset_of_slice() { self.require_type_has_static_alignment( field_ty, expr.span, @@ -3675,7 +3675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && field.name == sym::integer(index) { if let Some(&field_ty) = tys.get(index) { - if self.tcx.features().offset_of_slice { + if self.tcx.features().offset_of_slice() { self.require_type_has_static_alignment( field_ty, expr.span, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2bc84d1ac6735..d2d311ef5654f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1486,7 +1486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return ty::Const::new_error(self.tcx, guar); } } - } else if self.tcx.features().generic_const_exprs { + } else if self.tcx.features().generic_const_exprs() { ct.normalize_internal(self.tcx, self.param_env) } else { ct diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index e60bd1a312a1b..4123feebb407f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -404,7 +404,7 @@ fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior { } // `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff - if tcx.features().never_type_fallback { + if tcx.features().never_type_fallback() { return DivergingFallbackBehavior::ContextDependent; } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 5ae8d2230f8ff..f427b0b805eb5 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -141,7 +141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { let var_ty = self.assign(p.span, p.hir_id, None); if let Some((ty_span, hir_id)) = self.outermost_fn_param_pat { - if !self.fcx.tcx.features().unsized_fn_params { + if !self.fcx.tcx.features().unsized_fn_params() { self.fcx.require_type_is_sized( var_ty, ty_span, @@ -158,7 +158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { ), ); } - } else if !self.fcx.tcx.features().unsized_locals { + } else if !self.fcx.tcx.features().unsized_locals() { self.fcx.require_type_is_sized( var_ty, p.span, diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 85ee0a5cf7dab..85e11ff674500 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -161,7 +161,7 @@ fn typeck_with_fallback<'tcx>( let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig); let fn_sig = fcx.normalize(body.value.span, fn_sig); - check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params); + check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params()); } else { let expected_type = infer_type_if_missing(&fcx, node); let expected_type = expected_type.unwrap_or_else(fallback); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 1d7b3433fe5cb..f4685725dd30f 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -536,7 +536,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // FIXME(arbitrary_self_types): We probably should limit the // situations where this can occur by adding additional restrictions // to the feature, like the self type can't reference method args. - if self.tcx.features().arbitrary_self_types { + if self.tcx.features().arbitrary_self_types() { self.err_ctxt() .report_mismatched_types(&cause, method_self_ty, self_ty, terr) .emit(); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1be711887d9fa..b60fa8bbfa148 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mode, })); } else if bad_ty.reached_raw_pointer - && !self.tcx.features().arbitrary_self_types_pointers + && !self.tcx.features().arbitrary_self_types_pointers() && !self.tcx.sess.at_least_rust_2018() { // this case used to be allowed by the compiler, @@ -429,8 +429,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(ty.value); let guar = match *ty.kind() { ty::Infer(ty::TyVar(_)) => { - let raw_ptr_call = - bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types; + let raw_ptr_call = bad_ty.reached_raw_pointer + && !self.tcx.features().arbitrary_self_types(); let mut err = self.err_ctxt().emit_inference_failure_err( self.body_id, span, @@ -1146,7 +1146,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } ty::Adt(def, args) - if self.tcx.features().pin_ergonomics + if self.tcx.features().pin_ergonomics() && self.tcx.is_lang_item(def.did(), hir::LangItem::Pin) => { // make sure this is a pinned reference (and not a `Pin` or something) @@ -1195,7 +1195,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self_ty: Ty<'tcx>, unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, ) -> Option> { - if !self.tcx.features().pin_ergonomics { + if !self.tcx.features().pin_ergonomics() { return None; } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index e961752b24c2c..cba6586f01dd8 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -442,7 +442,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let features = self.tcx.features(); - if features.ref_pat_eat_one_layer_2024 || features.ref_pat_eat_one_layer_2024_structural { + if features.ref_pat_eat_one_layer_2024() || features.ref_pat_eat_one_layer_2024_structural() + { def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl()); if def_br == ByRef::Yes(Mutability::Not) { max_ref_mutbl = MutblCap::Not; @@ -490,7 +491,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - if self.tcx.features().string_deref_patterns + if self.tcx.features().string_deref_patterns() && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind { let tcx = self.tcx; @@ -675,10 +676,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let bm = match user_bind_annot { BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => { if pat.span.at_least_rust_2024() - && (self.tcx.features().ref_pat_eat_one_layer_2024 - || self.tcx.features().ref_pat_eat_one_layer_2024_structural) + && (self.tcx.features().ref_pat_eat_one_layer_2024() + || self.tcx.features().ref_pat_eat_one_layer_2024_structural()) { - if !self.tcx.features().mut_ref { + if !self.tcx.features().mut_ref() { feature_err( &self.tcx.sess, sym::mut_ref, @@ -2152,8 +2153,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let tcx = self.tcx; let features = tcx.features(); - let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024; - let ref_pat_eat_one_layer_2024_structural = features.ref_pat_eat_one_layer_2024_structural; + let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024(); + let ref_pat_eat_one_layer_2024_structural = + features.ref_pat_eat_one_layer_2024_structural(); let no_ref_mut_behind_and = ref_pat_eat_one_layer_2024 || ref_pat_eat_one_layer_2024_structural; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 63cf483aa2274..9e8a314bc4ae4 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -488,7 +488,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let final_upvar_tys = self.final_upvar_tys(closure_def_id); debug!(?closure_hir_id, ?args, ?final_upvar_tys); - if self.tcx.features().unsized_locals || self.tcx.features().unsized_fn_params { + if self.tcx.features().unsized_locals() || self.tcx.features().unsized_fn_params() { for capture in self.typeck_results.borrow().closure_min_captures_flattened(closure_def_id) { diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index d3d092be2223f..391e640f8bcb9 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -830,7 +830,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased); // Normalize consts in writeback, because GCE doesn't normalize eagerly. - if tcx.features().generic_const_exprs { + if tcx.features().generic_const_exprs() { value = value.fold_with(&mut EagerlyNormalizeConsts { tcx, param_env: self.fcx.param_env }); } diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index a006786aa75b9..1f46155abc882 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -68,7 +68,7 @@ pub(crate) fn assert_dep_graph(tcx: TyCtxt<'_>) { // if the `rustc_attrs` feature is not enabled, then the // attributes we are interested in cannot be present anyway, so // skip the walk. - if !tcx.features().rustc_attrs { + if !tcx.features().rustc_attrs() { return; } diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index d25fe4219b587..2075d4214c134 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -140,7 +140,7 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { } // can't add `#[rustc_clean]` etc without opting into this feature - if !tcx.features().rustc_attrs { + if !tcx.features().rustc_attrs() { return; } diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs index 63a8a949e9699..9923f05df3c73 100644 --- a/compiler/rustc_lint/src/async_fn_in_trait.rs +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait { && let hir::IsAsync::Async(async_span) = sig.header.asyncness { // RTN can be used to bound `async fn` in traits in a better way than "always" - if cx.tcx.features().return_type_notation { + if cx.tcx.features().return_type_notation() { return; } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 125fe9b3f16ff..71c667b2cd6b6 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1235,7 +1235,7 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller { def_id: LocalDefId, ) { if fn_kind.asyncness().is_async() - && !cx.tcx.features().async_fn_track_caller + && !cx.tcx.features().async_fn_track_caller() // Now, check if the function has the `#[track_caller]` attribute && let Some(attr) = cx.tcx.get_attr(def_id, sym::track_caller) { @@ -1424,7 +1424,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`. let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) - && cx.tcx.features().generic_const_exprs + && cx.tcx.features().generic_const_exprs() { return; } @@ -1538,7 +1538,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { use rustc_middle::ty::ClauseKind; - if cx.tcx.features().trivial_bounds { + if cx.tcx.features().trivial_bounds() { let predicates = cx.tcx.predicates_of(item.owner_id); for &(predicate, span) in predicates.predicates { let predicate_kind_name = match predicate.kind().skip_binder() { diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 58fd11fcc293f..bdfcc2c0a1006 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -243,7 +243,7 @@ impl_lint_pass!( impl<'tcx> LateLintPass<'tcx> for IfLetRescope { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { - if expr.span.edition().at_least_rust_2024() || !cx.tcx.features().if_let_rescope { + if expr.span.edition().at_least_rust_2024() || !cx.tcx.features().if_let_rescope() { return; } if let (Level::Allow, _) = cx.tcx.lint_level_at_node(IF_LET_RESCOPE, expr.hir_id) { diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index d029ad934079b..cc40b67ab271d 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -263,8 +263,8 @@ where && parent == self.parent_def_id { let opaque_span = self.tcx.def_span(opaque_def_id); - let new_capture_rules = - opaque_span.at_least_rust_2024() || self.tcx.features().lifetime_capture_rules_2024; + let new_capture_rules = opaque_span.at_least_rust_2024() + || self.tcx.features().lifetime_capture_rules_2024(); if !new_capture_rules && !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) { diff --git a/compiler/rustc_lint/src/tail_expr_drop_order.rs b/compiler/rustc_lint/src/tail_expr_drop_order.rs index 44a36142ed480..04f769bf5517f 100644 --- a/compiler/rustc_lint/src/tail_expr_drop_order.rs +++ b/compiler/rustc_lint/src/tail_expr_drop_order.rs @@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for TailExprDropOrder { _: Span, def_id: rustc_span::def_id::LocalDefId, ) { - if cx.tcx.sess.at_least_rust_2024() && cx.tcx.features().shorter_tail_lifetimes { + if cx.tcx.sess.at_least_rust_2024() && cx.tcx.features().shorter_tail_lifetimes() { Self::check_fn_or_closure(cx, fn_kind, body, def_id); } } diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 39fa23766b5d2..641d1d8e79819 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -170,7 +170,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { let mut upstream_in_dylibs = FxHashSet::default(); - if tcx.features().rustc_private { + if tcx.features().rustc_private() { // We need this to prevent users of `rustc_driver` from linking dynamically to `std` // which does not work as `std` is also statically linked into `rustc_driver`. diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index c7953d50406ac..1e6bc413118ec 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -265,7 +265,7 @@ impl<'tcx> Collector<'tcx> { NativeLibKind::RawDylib } "link-arg" => { - if !features.link_arg_attribute { + if !features.link_arg_attribute() { feature_err( sess, sym::link_arg_attribute, @@ -314,7 +314,7 @@ impl<'tcx> Collector<'tcx> { .emit_err(errors::LinkCfgSinglePredicate { span: item.span() }); continue; }; - if !features.link_cfg { + if !features.link_cfg() { feature_err( sess, sym::link_cfg, @@ -384,7 +384,7 @@ impl<'tcx> Collector<'tcx> { }; macro report_unstable_modifier($feature: ident) { - if !features.$feature { + if !features.$feature() { // FIXME: make this translatable #[expect(rustc::untranslatable_diagnostic)] feature_err( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index afe03531861c9..ec678c7515b0d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1765,7 +1765,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_stability(&mut self, def_id: DefId) { // The query lookup can take a measurable amount of time in crates with many items. Check if // the stability attributes are even enabled before using their queries. - if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { + if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_stability(def_id) { record!(self.tables.lookup_stability[def_id] <- stab) } @@ -1776,7 +1776,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_const_stability(&mut self, def_id: DefId) { // The query lookup can take a measurable amount of time in crates with many items. Check if // the stability attributes are even enabled before using their queries. - if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { + if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_const_stability(def_id) { record!(self.tables.lookup_const_stability[def_id] <- stab) } @@ -1787,7 +1787,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_default_body_stability(&mut self, def_id: DefId) { // The query lookup can take a measurable amount of time in crates with many items. Check if // the stability attributes are even enabled before using their queries. - if self.feat.staged_api || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { + if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_default_body_stability(def_id) { record!(self.tables.lookup_default_body_stability[def_id] <- stab) } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 59bc55269a30a..2ecf1d0bcf856 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -116,7 +116,7 @@ impl<'tcx> TyCtxt<'tcx> { // @lcnr believes that successfully evaluating even though there are // used generic parameters is a bug of evaluation, so checking for it // here does feel somewhat sensible. - if !self.features().generic_const_exprs && ct.args.has_non_region_param() { + if !self.features().generic_const_exprs() && ct.args.has_non_region_param() { let def_kind = self.def_kind(instance.def_id()); assert!( matches!( diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 26dcae001e0eb..515aabbe2fc8a 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -61,7 +61,7 @@ pub enum OverlapMode { impl OverlapMode { pub fn get(tcx: TyCtxt<'_>, trait_id: DefId) -> OverlapMode { - let with_negative_coherence = tcx.features().with_negative_coherence; + let with_negative_coherence = tcx.features().with_negative_coherence(); let strict_coherence = tcx.has_attr(trait_id, sym::rustc_strict_coherence); if with_negative_coherence { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9ffdcf646acec..b682524ae39f4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -710,15 +710,15 @@ impl<'tcx> rustc_type_ir::inherent::Safety> for hir::Safety { impl<'tcx> rustc_type_ir::inherent::Features> for &'tcx rustc_feature::Features { fn generic_const_exprs(self) -> bool { - self.generic_const_exprs + self.generic_const_exprs() } fn coroutine_clone(self) -> bool { - self.coroutine_clone + self.coroutine_clone() } fn associated_const_equality(self) -> bool { - self.associated_const_equality + self.associated_const_equality() } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index dbf88e643c56b..7e65df6b27ce7 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -398,7 +398,7 @@ impl<'tcx> SizeSkeleton<'tcx> { ), } } - ty::Array(inner, len) if tcx.features().transmute_generic_consts => { + ty::Array(inner, len) if tcx.features().transmute_generic_consts() => { let len_eval = len.try_to_target_usize(tcx); if len_eval == Some(0) { return Ok(SizeSkeleton::Known(Size::from_bytes(0), None)); diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index b5495fa282b65..10c3522eb0e98 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1208,7 +1208,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } } - if self.tcx().features().return_type_notation + if self.tcx().features().return_type_notation() && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = self.tcx().opt_rpitit_info(def_id) && let ty::Alias(_, alias_ty) = diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 74de378c4d78e..d8362ccc0a97c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -750,7 +750,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_diverging_default(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - if tcx.features().never_type_fallback { tcx.types.never } else { tcx.types.unit } + if tcx.features().never_type_fallback() { tcx.types.never } else { tcx.types.unit } } // lang and diagnostic tys diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9a3049f3be6db..06cbb6c9f1d86 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -877,8 +877,8 @@ impl<'tcx> TyCtxt<'tcx> { // FIXME(effects): This is suspicious and should probably not be done, // especially now that we enforce host effects and then properly handle // effect vars during fallback. - let mut host_always_on = - !self.features().effects || self.sess.opts.unstable_opts.unleash_the_miri_inside_of_you; + let mut host_always_on = !self.features().effects() + || self.sess.opts.unstable_opts.unleash_the_miri_inside_of_you; // Compute the constness required by the context. let const_context = self.hir().body_const_context(def_id); @@ -1826,8 +1826,8 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { /// cause an ICE that we otherwise may want to prevent. pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) - && tcx.features().intrinsics) - || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs) + && tcx.features().intrinsics()) + || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs()) { Some(ty::IntrinsicDef { name: tcx.item_name(def_id.into()), diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index 1e67e759aa20a..112eac32264f4 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -163,7 +163,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = this.tcx; - if tcx.features().unsized_fn_params { + if tcx.features().unsized_fn_params() { let ty = expr.ty; let param_env = this.param_env; diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 7170aebee7d22..37cedd8cf5cd9 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let ty::Adt(def, _) = ty.kind() && tcx.is_lang_item(def.did(), LangItem::String) { - if !tcx.features().string_deref_patterns { + if !tcx.features().string_deref_patterns() { span_bug!( test.span, "matching on `String` went through without enabling string_deref_patterns" diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 5995d60e7e073..5faefe2f25f41 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -777,7 +777,7 @@ impl<'tcx> Cx<'tcx> { if_then_scope: region::Scope { id: then.hir_id.local_id, data: { - if expr.span.at_least_rust_2024() && tcx.features().if_let_rescope { + if expr.span.at_least_rust_2024() && tcx.features().if_let_rescope() { region::ScopeData::IfThenRescope } else { region::ScopeData::IfThen diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index ae77bce6bb199..8498df59ce653 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1126,7 +1126,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( .map(|witness| cx.print_witness_pat(witness)) .collect::>() .join(" | "); - if witnesses.iter().all(|p| p.is_never_pattern()) && cx.tcx.features().never_patterns { + if witnesses.iter().all(|p| p.is_never_pattern()) && cx.tcx.features().never_patterns() { // Arms with a never pattern don't take a body. pattern } else { diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 0a413d68020dc..cd29105897778 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1497,7 +1497,7 @@ fn check_field_tys_sized<'tcx>( ) { // No need to check if unsized_locals/unsized_fn_params is disabled, // since we will error during typeck. - if !tcx.features().unsized_locals && !tcx.features().unsized_fn_params { + if !tcx.features().unsized_locals() && !tcx.features().unsized_fn_params() { return; } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index daf868559bcae..79c62372df028 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -288,7 +288,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()), evaluated: IndexVec::with_capacity(num_values), next_opaque: Some(1), - feature_unsized_locals: tcx.features().unsized_locals, + feature_unsized_locals: tcx.features().unsized_locals(), ssa, dominators, reused_locals: BitSet::new_empty(local_decls.len()), diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index d0cc123c41a8a..b1267562f7b8c 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -12,7 +12,7 @@ use super::layout_test::ensure_wf; use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedField}; pub fn test_abi(tcx: TyCtxt<'_>) { - if !tcx.features().rustc_attrs { + if !tcx.features().rustc_attrs() { // if the `rustc_attrs` feature is not enabled, don't bother testing ABI return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 298c065b0599a..8644284482385 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1187,7 +1187,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { sym::rust_logo => { if self.check_attr_crate_level(attr, meta, hir_id) - && !self.tcx.features().rustdoc_internals + && !self.tcx.features().rustdoc_internals() { feature_err( &self.tcx.sess, @@ -1774,7 +1774,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } sym::align => { if let (Target::Fn | Target::Method(MethodKind::Inherent), false) = - (target, self.tcx.features().fn_align) + (target, self.tcx.features().fn_align()) { feature_err( &self.tcx.sess, diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index ca13ca11673fa..f5ece513956e2 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -105,7 +105,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { // If this crate is not using stability attributes, or this function is not claiming to be a // stable `const fn`, that is all that is required. - if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) { + if !tcx.features().staged_api() || tcx.has_attr(def_id, sym::rustc_const_unstable) { return true; } diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 3aef88e771f51..93729a7f6df8c 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -18,7 +18,7 @@ use crate::errors::{ }; pub fn test_layout(tcx: TyCtxt<'_>) { - if !tcx.features().rustc_attrs { + if !tcx.features().rustc_attrs() { // if the `rustc_attrs` feature is not enabled, don't bother testing layout return; } diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 91ba2fa7548f7..8a360c017adbf 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -144,7 +144,7 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> { fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures { // If `staged_api` is not enabled then we aren't allowed to define lib // features; there is no point collecting them. - if !tcx.features().staged_api { + if !tcx.features().staged_api() { return LibFeatures::default(); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 80ac2741c3864..1bbb0caa58d3e 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -144,7 +144,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } } - if !self.tcx.features().staged_api { + if !self.tcx.features().staged_api() { // Propagate unstability. This can happen even for non-staged-api crates in case // -Zforce-unstable-if-unmarked is set. if let Some(stab) = self.parent_stab { @@ -541,7 +541,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { } fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) { - if !self.tcx.features().staged_api { + if !self.tcx.features().staged_api() { return; } @@ -734,7 +734,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // items. hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => { let features = self.tcx.features(); - if features.staged_api { + if features.staged_api() { let attrs = self.tcx.hir().attrs(item.hir_id()); let stab = attr::find_stability(self.tcx.sess, attrs, item.span); let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item.span); @@ -762,7 +762,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable // needs to have an error emitted. - if features.const_trait_impl + if features.const_trait_impl() && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id()) && const_stab.is_some_and(|(stab, _)| stab.is_const_stable()) { @@ -926,7 +926,7 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> { /// libraries, identify activated features that don't exist and error about them. pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let is_staged_api = - tcx.sess.opts.unstable_opts.force_unstable_if_unmarked || tcx.features().staged_api; + tcx.sess.opts.unstable_opts.force_unstable_if_unmarked || tcx.features().staged_api(); if is_staged_api { let effective_visibilities = &tcx.effective_visibilities(()); let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities }; diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 70a9319d6668e..0e132b27fb4cd 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -891,7 +891,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); s } - Never if self.tcx.features().never_patterns => "!".to_string(), + Never if self.tcx.features().never_patterns() => "!".to_string(), Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => "_".to_string(), Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, @@ -915,7 +915,7 @@ fn would_print_as_wildcard(tcx: TyCtxt<'_>, p: &WitnessPat<'_, '_>) -> bool { | Constructor::NonExhaustive | Constructor::Hidden | Constructor::PrivateUninhabited => true, - Constructor::Never if !tcx.features().never_patterns => true, + Constructor::Never if !tcx.features().never_patterns() => true, _ => false, } } @@ -929,7 +929,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { type PatData = &'p Pat<'tcx>; fn is_exhaustive_patterns_feature_on(&self) -> bool { - self.tcx.features().exhaustive_patterns + self.tcx.features().exhaustive_patterns() } fn ctor_arity(&self, ctor: &crate::constructor::Constructor, ty: &Self::Ty) -> usize { diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 78c37688d34c4..68b16a1291023 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -115,7 +115,7 @@ impl<'tcx> HashStable> for rustc_feature::Features { self.enabled_lang_features().hash_stable(hcx, hasher); self.enabled_lib_features().hash_stable(hcx, hasher); - self.all_lang_features()[..].hash_stable(hcx, hasher); + // FIXME: why do we hash something that is a compile-time constant? for feature in rustc_feature::UNSTABLE_FEATURES.iter() { feature.feature.name.hash_stable(hcx, hasher); } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 8ae77902bce60..b80e0e196ca08 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -606,7 +606,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) { Some(binding) => { if matches!(ident.name, sym::f16) - && !this.tcx.features().f16 + && !this.tcx.features().f16() && !ident.span.allows_unstable(sym::f16) && finalize.is_some() && innermost_result.is_none() @@ -620,7 +620,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .emit(); } if matches!(ident.name, sym::f128) - && !this.tcx.features().f128 + && !this.tcx.features().f128() && !ident.span.allows_unstable(sym::f128) && finalize.is_some() && innermost_result.is_none() diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 98db36b12be67..033cd7d58705d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2683,7 +2683,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.with_generic_param_rib( &generics.params, RibKind::Item( - if self.r.tcx.features().generic_const_items { + if self.r.tcx.features().generic_const_items() { HasGenericParams::Yes(generics.span) } else { HasGenericParams::No @@ -2888,7 +2888,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { RibKind::Normal => { // FIXME(non_lifetime_binders): Stop special-casing // const params to error out here. - if self.r.tcx.features().non_lifetime_binders + if self.r.tcx.features().non_lifetime_binders() && matches!(param.kind, GenericParamKind::Type { .. }) { Res::Def(def_kind, def_id.to_def_id()) @@ -4411,10 +4411,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let tcx = self.r.tcx(); let gate_err_sym_msg = match prim { - PrimTy::Float(FloatTy::F16) if !tcx.features().f16 => { + PrimTy::Float(FloatTy::F16) if !tcx.features().f16() => { Some((sym::f16, "the type `f16` is unstable")) } - PrimTy::Float(FloatTy::F128) if !tcx.features().f128 => { + PrimTy::Float(FloatTy::F128) if !tcx.features().f128() => { Some((sym::f128, "the type `f128` is unstable")) } _ => None, @@ -4565,7 +4565,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } AnonConstKind::InlineConst => ConstantHasGenerics::Yes, AnonConstKind::ConstArg(_) => { - if self.r.tcx.features().generic_const_exprs || is_trivial_const_arg { + if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg { ConstantHasGenerics::Yes } else { ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 50fbdcaf9dc28..f0632a21091bb 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1198,7 +1198,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // const generics. Of course, `Struct` and `Enum` may contain ty params, too, but the // benefits of including them here outweighs the small number of false positives. Some(Res::Def(DefKind::Struct | DefKind::Enum, _)) - if self.r.tcx.features().adt_const_params => + if self.r.tcx.features().adt_const_params() => { Applicability::MaybeIncorrect } @@ -2773,7 +2773,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Avoid suggesting placing lifetime parameters on constant items unless the relevant // feature is enabled. Suggest the parent item as a possible location if applicable. if let LifetimeBinderKind::ConstItem = kind - && !self.r.tcx().features().generic_const_items + && !self.r.tcx().features().generic_const_items() { continue; } @@ -2934,7 +2934,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .emit(); } NoConstantGenericsReason::NonTrivialConstArg => { - assert!(!self.r.tcx.features().generic_const_exprs); + assert!(!self.r.tcx.features().generic_const_exprs()); self.r .dcx() .create_err(errors::ParamInNonTrivialAnonConst { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 5e38fb5b6c51b..a9ebffea8a10b 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -661,7 +661,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // We are trying to avoid reporting this error if other related errors were reported. - if res != Res::Err && inner_attr && !self.tcx.features().custom_inner_attributes { + if res != Res::Err && inner_attr && !self.tcx.features().custom_inner_attributes() { let is_macro = match res { Res::Def(..) => true, Res::NonMacroAttr(..) => false, @@ -690,7 +690,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && namespace.ident.name == sym::diagnostic && !(attribute.ident.name == sym::on_unimplemented || (attribute.ident.name == sym::do_not_recommend - && self.tcx.features().do_not_recommend)) + && self.tcx.features().do_not_recommend())) { let distance = edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5); diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index 8cfb65c1c5097..73bd8d7555b89 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -18,7 +18,7 @@ pub fn report_symbol_names(tcx: TyCtxt<'_>) { // if the `rustc_attrs` feature is not enabled, then the // attributes we are interested in cannot be present anyway, so // skip the walk. - if !tcx.features().rustc_attrs { + if !tcx.features().rustc_attrs() { return; } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 549beafd1969c..9ee4963a3603b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -3026,7 +3026,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, span: Span, ) -> Result, 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") diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ff542cfbec12f..1fe93cb017ab9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -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; } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index c258832bf2bef..1be3c96445465 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -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() { diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 364a13b3a7599..cc0450e0b057b 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -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() { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e56f186697072..2bdeb00bdacba 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index cffb9b5984167..cdf24887e763b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -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; } diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index d246d37f74865..12e00ec79ac47 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -402,7 +402,7 @@ impl<'a, 'b, 'tcx> TypeFolder> 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 diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index cc634b65a0bf5..38722c0ff7c5c 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index ac38c9e24a290..eea3867190d3e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -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; } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9a49fd7e77e9c..e7d3004aa203c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -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", diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4757430a21cba..d5b1c5a97daa6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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 = diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index b82a343364581..0e45f7a195f04 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -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`? diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index f8d98eb856e8e..23b5f62b5ca49 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -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)) diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 07e68e5a3e81b..8904a9a685807 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -836,7 +836,7 @@ impl<'a, 'tcx> TypeVisitor> 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() { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index a057caa932952..a3210dd80d77b 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -181,7 +181,7 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { // don't synthesize the associated type even if the user has written `const_trait` // if the effects feature is disabled. - if !tcx.features().effects { + if !tcx.features().effects() { return None; } let (feed, parent_did) = match tcx.def_kind(def_id) { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 391985ce88a21..4b770d9938c2b 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -406,7 +406,7 @@ fn thir_abstract_const<'tcx>( tcx: TyCtxt<'tcx>, def: LocalDefId, ) -> Result>>, ErrorGuaranteed> { - if !tcx.features().generic_const_exprs { + if !tcx.features().generic_const_exprs() { return Ok(None); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 848f2abe6a9f0..bf168809e28c4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2189,7 +2189,7 @@ pub(crate) fn clean_middle_ty<'tcx>( } ty::Alias(ty::Weak, data) => { - if cx.tcx.features().lazy_type_alias { + if cx.tcx.features().lazy_type_alias() { // Weak type alias `data` represents the `type X` in `type X = Y`. If we need `Y`, // we need to use `type_of`. let path = clean_middle_path( diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2e3050eee2fb0..6090de16d55bc 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -966,8 +966,8 @@ pub(crate) trait AttributesExt { fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet) -> Option> { let sess = tcx.sess; - let doc_cfg_active = tcx.features().doc_cfg; - let doc_auto_cfg_active = tcx.features().doc_auto_cfg; + let doc_cfg_active = tcx.features().doc_cfg(); + let doc_auto_cfg_active = tcx.features().doc_auto_cfg(); fn single(it: T) -> Option { let mut iter = it.into_iter(); diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index f4579d8553150..484bdb5627c37 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -116,7 +116,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item find_testable_code(dox, &mut tests, ErrorCodes::No, false, None); - if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples { + if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples() { if should_have_doc_example(cx, item) { debug!("reporting error for {item:?} (hir_id={hir_id:?})"); let sp = item.attr_span(cx.tcx); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 2f0ea8d618c12..140fda7091885 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1419,7 +1419,7 @@ impl LinkCollector<'_, '_> { && key.path_str.contains("::") // We only want to check this if this is an associated item. { - if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers { + if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers() { self.report_rawptr_assoc_feature_gate(diag.dox, &diag.link_range, diag.item); return None; } else { diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs index 70eb81fa09c1a..b0389fd9a2f62 100644 --- a/src/tools/clippy/clippy_lints/src/empty_enum.rs +++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs @@ -64,7 +64,7 @@ impl LateLintPass<'_> for EmptyEnum { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { if let ItemKind::Enum(..) = item.kind // Only suggest the `never_type` if the feature is enabled - && cx.tcx.features().never_type + && cx.tcx.features().never_type() && let Some(adt) = cx.tcx.type_of(item.owner_id).instantiate_identity().ty_adt_def() && adt.variants().is_empty() { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index f9ffbc5dc0b8e..20984bc40caf3 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -114,7 +114,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect(); for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) { if matches!(arm2.pat.kind, PatKind::Wild) { - if !cx.tcx.features().non_exhaustive_omitted_patterns_lint + if !cx.tcx.features().non_exhaustive_omitted_patterns_lint() || is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id) { let arm_span = adjusted_arm_span(cx, arm1.span); diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs index 564c598a334c7..42d9efe4ff6fd 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs @@ -251,7 +251,7 @@ fn emit_redundant_guards<'tcx>( fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { for_each_expr_without_closures(expr, |expr| { if match expr.kind { - ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat, + ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat(), ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => { // Allow ctors matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..)) From 7340b9c7c2056ad994aac0071f44f7323d751fa9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 23 Oct 2024 07:29:25 +0100 Subject: [PATCH 2/5] rustc_feature: remove no-longer-needed macro --- compiler/rustc_feature/src/builtin_attrs.rs | 46 ++++++++++----------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5ba4491e97f5c..753195bf691c0 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -12,33 +12,31 @@ use crate::{Features, Stability}; type GateFn = fn(&Features) -> bool; -macro_rules! cfg_fn { - ($field: ident) => { - Features::$field as GateFn - }; -} - pub type GatedCfg = (Symbol, Symbol, GateFn); /// `cfg(...)`'s that are feature gated. const GATED_CFGS: &[GatedCfg] = &[ // (name in cfg, feature, function to check if the feature is enabled) - (sym::overflow_checks, sym::cfg_overflow_checks, cfg_fn!(cfg_overflow_checks)), - (sym::ub_checks, sym::cfg_ub_checks, cfg_fn!(cfg_ub_checks)), - (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), + (sym::overflow_checks, sym::cfg_overflow_checks, Features::cfg_overflow_checks), + (sym::ub_checks, sym::cfg_ub_checks, Features::cfg_ub_checks), + (sym::target_thread_local, sym::cfg_target_thread_local, Features::cfg_target_thread_local), ( sym::target_has_atomic_equal_alignment, sym::cfg_target_has_atomic_equal_alignment, - cfg_fn!(cfg_target_has_atomic_equal_alignment), - ), - (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), - (sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)), - (sym::version, sym::cfg_version, cfg_fn!(cfg_version)), - (sym::relocation_model, sym::cfg_relocation_model, cfg_fn!(cfg_relocation_model)), - (sym::sanitizer_cfi_generalize_pointers, sym::cfg_sanitizer_cfi, cfg_fn!(cfg_sanitizer_cfi)), - (sym::sanitizer_cfi_normalize_integers, sym::cfg_sanitizer_cfi, cfg_fn!(cfg_sanitizer_cfi)), + Features::cfg_target_has_atomic_equal_alignment, + ), + ( + sym::target_has_atomic_load_store, + sym::cfg_target_has_atomic, + Features::cfg_target_has_atomic, + ), + (sym::sanitize, sym::cfg_sanitize, Features::cfg_sanitize), + (sym::version, sym::cfg_version, Features::cfg_version), + (sym::relocation_model, sym::cfg_relocation_model, Features::cfg_relocation_model), + (sym::sanitizer_cfi_generalize_pointers, sym::cfg_sanitizer_cfi, Features::cfg_sanitizer_cfi), + (sym::sanitizer_cfi_normalize_integers, sym::cfg_sanitizer_cfi, Features::cfg_sanitizer_cfi), // this is consistent with naming of the compiler flag it's for - (sym::fmt_debug, sym::fmt_debug, cfg_fn!(fmt_debug)), + (sym::fmt_debug, sym::fmt_debug, Features::fmt_debug), ]; /// Find a gated cfg determined by the `pred`icate which is given the cfg's name. @@ -220,7 +218,7 @@ macro_rules! gated { safety: AttributeSafety::Unsafe, template: $tpl, duplicates: $duplicates, - gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), + gate: Gated(Stability::Unstable, sym::$gate, $msg, Features::$gate), } }; (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { @@ -231,7 +229,7 @@ macro_rules! gated { safety: AttributeSafety::Unsafe, template: $tpl, duplicates: $duplicates, - gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), + gate: Gated(Stability::Unstable, sym::$attr, $msg, Features::$attr), } }; ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { @@ -242,7 +240,7 @@ macro_rules! gated { safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, - gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), + gate: Gated(Stability::Unstable, sym::$gate, $msg, Features::$gate), } }; ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { @@ -253,7 +251,7 @@ macro_rules! gated { safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, - gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), + gate: Gated(Stability::Unstable, sym::$attr, $msg, Features::$attr), } }; } @@ -282,7 +280,7 @@ macro_rules! rustc_attr { safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, - gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), + gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, Features::rustc_attrs), } }; } @@ -935,7 +933,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ Stability::Unstable, sym::rustc_attrs, "diagnostic items compiler internal support for linting", - cfg_fn!(rustc_attrs), + Features::rustc_attrs, ), }, gated!( From 6ad17bd30c68c90792cb0e4fca8208be41493f6b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 23 Oct 2024 07:34:35 +0100 Subject: [PATCH 3/5] get rid of feature list in target feature logic --- .../rustc_codegen_ssa/src/target_features.rs | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index d99307106092f..0845bcc5749f4 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -5,7 +5,6 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::Applicability; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; -use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::TargetFeature; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; @@ -61,30 +60,9 @@ pub(crate) fn from_target_feature( return None; }; - // Only allow features whose feature gates have been enabled. + // Only allow target features whose feature gates have been enabled. let allowed = match feature_gate.as_ref().copied() { - Some(sym::arm_target_feature) => rust_features.arm_target_feature(), - Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature(), - Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature(), - Some(sym::mips_target_feature) => rust_features.mips_target_feature(), - Some(sym::riscv_target_feature) => rust_features.riscv_target_feature(), - Some(sym::avx512_target_feature) => rust_features.avx512_target_feature(), - Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature(), - Some(sym::tbm_target_feature) => rust_features.tbm_target_feature(), - Some(sym::wasm_target_feature) => rust_features.wasm_target_feature(), - Some(sym::rtm_target_feature) => rust_features.rtm_target_feature(), - Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature(), - Some(sym::bpf_target_feature) => rust_features.bpf_target_feature(), - Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature(), - Some(sym::csky_target_feature) => rust_features.csky_target_feature(), - Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature(), - Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature(), - Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature(), - Some(sym::sha512_sm_x86) => rust_features.sha512_sm_x86(), - Some(sym::x86_amx_intrinsics) => rust_features.x86_amx_intrinsics(), - Some(sym::xop_target_feature) => rust_features.xop_target_feature(), - Some(sym::s390x_target_feature) => rust_features.s390x_target_feature(), - Some(name) => bug!("unknown target feature gate {}", name), + Some(name) => rust_features.enabled(name), None => true, }; if !allowed { From e82bca6f32bd74e018c8bd46fe33986eae514189 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 23 Oct 2024 08:18:19 +0100 Subject: [PATCH 4/5] remove no longer needd UnstableFeature type --- compiler/rustc_expand/src/config.rs | 2 +- compiler/rustc_feature/src/lib.rs | 4 ++-- compiler/rustc_feature/src/unstable.rs | 16 +++++----------- .../rustc_query_system/src/ich/impls_syntax.rs | 2 +- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 7546c830a0b38..af27077f24289 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -103,7 +103,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - } // If the enabled feature is unstable, record it. - if UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_some() { + if UNSTABLE_FEATURES.iter().find(|f| name == f.name).is_some() { // When the ICE comes from core, alloc or std (approximation of the standard // library), there's a chance that the person hitting the ICE may be using // -Zbuild-std or similar with an untested target. The bug is probably in the diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 8f4c0b0ac95f9..7c4996c1412b8 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -94,8 +94,8 @@ impl UnstableFeatures { fn find_lang_feature_issue(feature: Symbol) -> Option> { // Search in all the feature lists. - if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| f.feature.name == feature) { - return f.feature.issue; + if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| f.name == feature) { + return f.issue; } if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| f.name == feature) { return f.issue; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 93e91c0984c71..9c6de079e2fa8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -6,10 +6,6 @@ use rustc_span::symbol::{Symbol, sym}; use super::{Feature, to_nonzero}; -pub struct UnstableFeature { - pub feature: Feature, -} - #[derive(PartialEq)] enum FeatureStatus { Default, @@ -82,13 +78,11 @@ macro_rules! declare_features { )+) => { /// Unstable language features that are being implemented or being /// considered for acceptance (stabilization) or removal. - pub const UNSTABLE_FEATURES: &[UnstableFeature] = &[ - $(UnstableFeature { - feature: Feature { - name: sym::$feature, - since: $ver, - issue: to_nonzero($issue), - }, + pub const UNSTABLE_FEATURES: &[Feature] = &[ + $(Feature { + name: sym::$feature, + since: $ver, + issue: to_nonzero($issue), }),+ ]; diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 68b16a1291023..52dd336313ad4 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -117,7 +117,7 @@ impl<'tcx> HashStable> for rustc_feature::Features { // FIXME: why do we hash something that is a compile-time constant? for feature in rustc_feature::UNSTABLE_FEATURES.iter() { - feature.feature.name.hash_stable(hcx, hasher); + feature.name.hash_stable(hcx, hasher); } } } From 44638853f545632c68d9a85f85df3418ae09f248 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 23 Oct 2024 08:20:02 +0100 Subject: [PATCH 5/5] rename lang feature lists to include LANG --- compiler/rustc_expand/src/config.rs | 9 +++++---- compiler/rustc_feature/src/accepted.rs | 2 +- compiler/rustc_feature/src/lib.rs | 12 ++++++------ compiler/rustc_feature/src/removed.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 2 +- compiler/rustc_passes/src/stability.rs | 6 +++--- compiler/rustc_query_system/src/ich/impls_syntax.rs | 2 +- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index af27077f24289..5bd9e2fbcb9bb 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -11,7 +11,8 @@ use rustc_ast::{ use rustc_attr as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_feature::{ - ACCEPTED_FEATURES, AttributeSafety, Features, REMOVED_FEATURES, UNSTABLE_FEATURES, + ACCEPTED_LANG_FEATURES, AttributeSafety, Features, REMOVED_LANG_FEATURES, + UNSTABLE_LANG_FEATURES, }; use rustc_lint_defs::BuiltinLintDiag; use rustc_parse::validate_attr; @@ -77,7 +78,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - }; // If the enabled feature has been removed, issue an error. - if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) { + if let Some(f) = REMOVED_LANG_FEATURES.iter().find(|f| name == f.feature.name) { sess.dcx().emit_err(FeatureRemoved { span: mi.span(), reason: f.reason.map(|reason| FeatureRemovedReason { reason }), @@ -86,7 +87,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - } // If the enabled feature is stable, record it. - if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { + if let Some(f) = ACCEPTED_LANG_FEATURES.iter().find(|f| name == f.name) { let since = Some(Symbol::intern(f.since)); features.set_enabled_lang_feature(name, mi.span(), since); continue; @@ -103,7 +104,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - } // If the enabled feature is unstable, record it. - if UNSTABLE_FEATURES.iter().find(|f| name == f.name).is_some() { + if UNSTABLE_LANG_FEATURES.iter().find(|f| name == f.name).is_some() { // When the ICE comes from core, alloc or std (approximation of the standard // library), there's a chance that the person hitting the ICE may be using // -Zbuild-std or similar with an untested target. The bug is probably in the diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 534458046945c..4f71bdaca1b13 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -9,7 +9,7 @@ macro_rules! declare_features { $(#[doc = $doc:tt])* (accepted, $feature:ident, $ver:expr, $issue:expr), )+) => { /// Formerly unstable features that have now been accepted (stabilized). - pub const ACCEPTED_FEATURES: &[Feature] = &[ + pub const ACCEPTED_LANG_FEATURES: &[Feature] = &[ $(Feature { name: sym::$feature, since: $ver, diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 7c4996c1412b8..216793485e55d 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -94,13 +94,13 @@ impl UnstableFeatures { fn find_lang_feature_issue(feature: Symbol) -> Option> { // Search in all the feature lists. - if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| f.name == feature) { + if let Some(f) = UNSTABLE_LANG_FEATURES.iter().find(|f| f.name == feature) { return f.issue; } - if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| f.name == feature) { + if let Some(f) = ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature) { return f.issue; } - if let Some(f) = REMOVED_FEATURES.iter().find(|f| f.feature.name == feature) { + if let Some(f) = REMOVED_LANG_FEATURES.iter().find(|f| f.feature.name == feature) { return f.feature.issue; } panic!("feature `{feature}` is not declared anywhere"); @@ -127,12 +127,12 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option { /// Formerly unstable features that have now been removed. - pub const REMOVED_FEATURES: &[RemovedFeature] = &[ + pub const REMOVED_LANG_FEATURES: &[RemovedFeature] = &[ $(RemovedFeature { feature: Feature { name: sym::$feature, diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 9c6de079e2fa8..8f4c208f1fbb5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -78,7 +78,7 @@ macro_rules! declare_features { )+) => { /// Unstable language features that are being implemented or being /// considered for acceptance (stabilization) or removal. - pub const UNSTABLE_FEATURES: &[Feature] = &[ + pub const UNSTABLE_LANG_FEATURES: &[Feature] = &[ $(Feature { name: sym::$feature, since: $ver, diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 1bbb0caa58d3e..a176b2bb1ad41 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -10,7 +10,7 @@ use rustc_attr::{ }; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; -use rustc_feature::ACCEPTED_FEATURES; +use rustc_feature::ACCEPTED_LANG_FEATURES; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId}; @@ -248,7 +248,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } if let Stability { level: Unstable { .. }, feature } = stab { - if ACCEPTED_FEATURES.iter().find(|f| f.name == feature).is_some() { + if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() { self.tcx .dcx() .emit_err(errors::UnstableAttrForAlreadyStableFeature { span, item_sp }); @@ -261,7 +261,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } if let Some(ConstStability { level: Unstable { .. }, feature, .. }) = const_stab { - if ACCEPTED_FEATURES.iter().find(|f| f.name == feature).is_some() { + if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() { self.tcx.dcx().emit_err(errors::UnstableAttrForAlreadyStableFeature { span: const_span.unwrap(), // If const_stab contains Some(..), same is true for const_span item_sp, diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 52dd336313ad4..29a28b10a068e 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -116,7 +116,7 @@ impl<'tcx> HashStable> for rustc_feature::Features { self.enabled_lib_features().hash_stable(hcx, hasher); // FIXME: why do we hash something that is a compile-time constant? - for feature in rustc_feature::UNSTABLE_FEATURES.iter() { + for feature in rustc_feature::UNSTABLE_LANG_FEATURES.iter() { feature.name.hash_stable(hcx, hasher); } }