Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cfa655a
tests: accept noundef in a couple more places
durin42 Sep 30, 2026
e75273b
core: io: clean `unused_variables` lint under `no_io_statics`
ojeda Oct 2, 2026
c52c194
always use next-solver in coherence
sjwang05 Aug 21, 2026
52aa198
make `coherence` and `globally` the only `NextSolverConfig` options
sjwang05 Aug 21, 2026
71e0361
remove intercrate ambiguity cause tracking from the old solver
sjwang05 Aug 21, 2026
097e1f3
mark TypingMode::Coherence arms in the old solver as unreachable
sjwang05 Aug 21, 2026
d850b33
bless tests
sjwang05 Aug 21, 2026
f3f9adf
tests: add test for warning-free builds of `core` under `no_io_statics`
ojeda Oct 2, 2026
da0baa2
reflection: fix ICE when TypeId::info called on ADT
yara-blue Oct 2, 2026
6065c5a
Make the tracking issue template better suited for experiments
tmandry Oct 2, 2026
89f50a5
ref: Avoid long iterator chain in all_rust_features
panstromek Oct 3, 2026
62cbb18
Add documentation for the and attributes
literally-user Oct 1, 2026
c7169e6
Rollup merge of #161491 - sjwang05:no-old-coherence, r=khyperia
JonathanBrouwer Oct 3, 2026
f025461
Rollup merge of #163627 - literally-user:docs-repr-no_main_attribute,…
JonathanBrouwer Oct 3, 2026
9022c22
Rollup merge of #163663 - yara-blue:reflection-ice-typeid-info, r=oli…
JonathanBrouwer Oct 3, 2026
4916d11
Rollup merge of #163561 - durin42:llvm-24-extra-noundefs, r=nikic
JonathanBrouwer Oct 3, 2026
6d49c57
Rollup merge of #163633 - ojeda:unused-variable-set_functions, r=John…
JonathanBrouwer Oct 3, 2026
50ecc0a
Rollup merge of #163681 - tmandry:issue-template-experiments, r=travi…
JonathanBrouwer Oct 3, 2026
7982402
Rollup merge of #163685 - panstromek:all_rust_features_iter, r=RalfJung
JonathanBrouwer Oct 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions .github/ISSUE_TEMPLATE/tracking_issue.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
---
name: Tracking Issue
about: A tracking issue for an accepted feature or RFC in Rust.
about: A tracking issue for an unstable feature in Rust.
title: Tracking Issue for XXX
labels: C-tracking-issue
---
<!--
NOTE: For library features, please use the "Library Tracking Issue" template instead.
Thank you for creating a tracking issue! 📜 Tracking issues are for tracking a
feature from implementation to stabilisation. Make sure to include the relevant
RFC for the feature if it has one. Otherwise provide a short summary of the
feature and link any relevant PRs or issues, and remove any sections that are
not relevant to the feature.
feature from implementation to stabilisation.
Remember to add team labels to the tracking issue.
For a language team feature, this would e.g., be `T-lang`.
For a language team feature, this would e.g., be `T-lang`:
> @rustbot label T-lang
Such a feature should also be labeled with e.g., `F-my_feature`.
This label is used to associate issues (e.g., bugs and design questions) to the feature.
-->

This is a tracking issue for the RFC "XXX" (rust-lang/rfcs#NNN).
The feature gate for the issue is `#![feature(FFF)]`.
This is a tracking issue for `#![feature(FFF)]`.
The RFC for this feature is rust-lang/rfcs#NNN.

<!--
Make sure to include the relevant RFC for the feature if it has one.
Otherwise, provide a short summary and motivation of the
feature and link any relevant PRs or issues.
Remove any sections that are not relevant to the feature.
-->

### About tracking issues

Expand All @@ -38,8 +46,8 @@ implementing a feature, followed by a PR that stabilises the feature. However
for larger features an implementation could be broken up into multiple PRs.
-->

- [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring
instructions?)
- [ ] Create the feature gate
- [ ] Implement the feature
- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
- [ ] Style updates for any new syntax ([nightly-style-procedure])
- [ ] Style team decision on new formatting
Expand All @@ -59,8 +67,8 @@ stabilised. It is useful to link related discussions and conculsions as they
develop.
-->

- [ ] list all the "unresolved questions" found in the RFC to ensure they are
not forgotten.
- [ ] List any unresolved questions, including those listed in the RFC if there is one,
to ensure they are not forgotten.

### Implementation history

Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_attr_parsing::AttributeParser;
use rustc_errors::msg;
use rustc_feature::{DependentFeature, Features};
use rustc_session::Session;
use rustc_session::config::NextSolverConfig;
use rustc_session::diagnostics::{feature_err, feature_warn};
use rustc_span::{Span, Spanned, sym};

Expand Down Expand Up @@ -698,7 +699,7 @@ fn check_dependent_features(sess: &Session, features: &Features) {
}

fn warn_next_solver_and_gce(sess: &Session, features: &Features) {
if !sess.opts.unstable_opts.next_solver.globally {
if sess.opts.unstable_opts.next_solver != NextSolverConfig::Globally {
return;
}

Expand All @@ -716,7 +717,7 @@ fn warn_next_solver_and_gce(sess: &Session, features: &Features) {
}

fn check_features_requiring_new_solver(sess: &Session, features: &Features) {
if sess.opts.unstable_opts.next_solver.globally {
if sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally {
return;
}

Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_const_eval/src/const_eval/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
self.project_downcast_named(&field_dest, sym::Slice)?;
variant
}
ty::Adt(adt_def, generics) => {
self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)?
}
ty::Adt(adt_def, _) => self.write_adt_type_info(&field_dest, *adt_def)?,
ty::Bool => {
let (variant, _variant_place) =
self.project_downcast_named(&field_dest, sym::Bool)?;
Expand Down
178 changes: 6 additions & 172 deletions compiler/rustc_const_eval/src/const_eval/type_info/adt.rs
Original file line number Diff line number Diff line change
@@ -1,204 +1,38 @@
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{
AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, VariantDef,
AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty,
};
use rustc_span::{bug, span_bug, sym};

use crate::const_eval::CompileTimeMachine;
use crate::interpret::{
CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Scalar, Writeable, interp_ok,
CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Writeable, interp_ok,
};

impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
// FIXME(type_info): No semver considerations for now
pub(crate) fn write_adt_type_info(
&mut self,
place: &impl Writeable<'tcx, CtfeProvenance>,
adt: (Ty<'tcx>, AdtDef<'tcx>),
generics: &'tcx GenericArgs<'tcx>,
adt_def: AdtDef<'tcx>,
) -> InterpResult<'tcx, VariantIdx> {
let (adt_ty, adt_def) = adt;
let variant_idx = match adt_def.adt_kind() {
AdtKind::Struct => {
let (variant, variant_place) = self.project_downcast_named(place, sym::Struct)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_struct_type_info(
place,
(adt_ty, adt_def.variant(VariantIdx::ZERO)),
generics,
)?;
let (variant, _) = self.project_downcast_named(place, sym::Struct)?;
variant
}
AdtKind::Union => {
let (variant, variant_place) = self.project_downcast_named(place, sym::Union)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_union_type_info(
place,
(adt_ty, adt_def.variant(VariantIdx::ZERO)),
generics,
)?;
let (variant, _) = self.project_downcast_named(place, sym::Union)?;
variant
}
AdtKind::Enum => {
let (variant, variant_place) = self.project_downcast_named(place, sym::Enum)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_enum_type_info(place, adt, generics)?;
let (variant, _) = self.project_downcast_named(place, sym::Enum)?;
variant
}
};
interp_ok(variant_idx)
}

pub(crate) fn write_struct_type_info(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
struct_: (Ty<'tcx>, &'tcx VariantDef),
generics: &'tcx GenericArgs<'tcx>,
) -> InterpResult<'tcx> {
let (struct_ty, struct_def) = struct_;
let struct_layout = self.layout_of(struct_ty)?;

for (field_idx, field) in
place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
{
let field_place = self.project_field(&place, field_idx)?;

match field.name {
sym::generics => self.write_generics(&field_place, generics)?,
sym::fields => {
self.write_variant_fields(field_place, struct_def, struct_layout, generics)?
}
sym::non_exhaustive => {
let is_non_exhaustive = struct_def.is_field_list_non_exhaustive();
self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)?
}
other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
}
}

interp_ok(())
}

pub(crate) fn write_union_type_info(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
union_: (Ty<'tcx>, &'tcx VariantDef),
generics: &'tcx GenericArgs<'tcx>,
) -> InterpResult<'tcx> {
let (union_ty, union_def) = union_;
let union_layout = self.layout_of(union_ty)?;

for (field_idx, field) in
place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
{
let field_place = self.project_field(&place, field_idx)?;

match field.name {
sym::generics => self.write_generics(&field_place, generics)?,
sym::fields => {
self.write_variant_fields(field_place, union_def, union_layout, generics)?
}
sym::non_exhaustive => {
let is_non_exhaustive = union_def.is_field_list_non_exhaustive();
self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)?
}
other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
}
}

interp_ok(())
}

pub(crate) fn write_enum_type_info(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
enum_: (Ty<'tcx>, AdtDef<'tcx>),
generics: &'tcx GenericArgs<'tcx>,
) -> InterpResult<'tcx> {
let (enum_ty, enum_def) = enum_;
let enum_layout = self.layout_of(enum_ty)?;

for (field_idx, field) in
place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
{
let field_place = self.project_field(&place, field_idx)?;

match field.name {
sym::generics => self.write_generics(&field_place, generics)?,
sym::type_id_variants => {
self.allocate_fill_and_write_slice_ptr(
&field_place,
enum_def.variants().len() as u64,
|this, i, place| {
let variant_idx = VariantIdx::from_usize(i as usize);
let variant_def = &enum_def.variants()[variant_idx];
let variant_layout = enum_layout.for_variant(this, variant_idx);
this.write_enum_variant(place, (variant_layout, &variant_def), generics)
},
)?;
}
sym::non_exhaustive => {
let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive();
self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)?
}
other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
}
}

interp_ok(())
}

fn write_enum_variant(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
variant: (TyAndLayout<'tcx>, &'tcx VariantDef),
generics: &'tcx GenericArgs<'tcx>,
) -> InterpResult<'tcx> {
let (variant_layout, variant_def) = variant;

for (field_idx, field_def) in
place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
{
let field_place = self.project_field(&place, field_idx)?;
match field_def.name {
sym::name => {
let name_place = self.allocate_str_dedup(variant_def.name.as_str())?;
let ptr = self.mplace_to_imm_ptr(&name_place, None)?;
self.write_immediate(*ptr, &field_place)?
}
sym::fields => {
self.write_variant_fields(field_place, &variant_def, variant_layout, generics)?
}
sym::non_exhaustive => {
let is_non_exhaustive = variant_def.is_field_list_non_exhaustive();
self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)?
}
other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"),
}
}
interp_ok(())
}

// Write fields for struct, enum variants
fn write_variant_fields(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
variant_def: &'tcx VariantDef,
variant_layout: TyAndLayout<'tcx>,
generics: &'tcx GenericArgs<'tcx>,
) -> InterpResult<'tcx> {
self.allocate_fill_and_write_slice_ptr(
&place,
variant_def.fields.len() as u64,
|this, i, place| {
let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)];
let field_ty = field_def.ty(*this.tcx, generics).skip_norm_wip();
this.write_field(field_ty, place, variant_layout, Some(field_def.name), i)
},
)
}

pub(super) fn write_generics(
&mut self,
place: &impl Writeable<'tcx, CtfeProvenance>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ fn orphan_check<'tcx>(
// (1) Instantiate all generic params with fresh inference vars.
let infcx = tcx
.infer_ctxt()
.with_next_trait_solver(tcx.next_trait_solver_in_coherence())
.with_next_trait_solver(true)
.enable_next_solver_overflow_fcw(false)
.build(TypingMode::Coherence);
let cause = traits::ObligationCause::dummy();
Expand Down
16 changes: 2 additions & 14 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ fn test_unstable_options_tracking_hash() {
// tidy-alphabetical-end
// FIXME(#160895): We don't test this when the next-solver is enabled by default.
if option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_none() {
tracked!(next_solver, NextSolverConfig { coherence: true, globally: true });
tracked!(next_solver, NextSolverConfig::Globally);
}
// tidy-alphabetical-start
tracked!(no_generate_arange_section, true);
Expand Down Expand Up @@ -948,7 +948,7 @@ fn test_edition_parsing() {

#[test]
fn test_assumptions_on_binders_enables_next_solver_globally() {
let globally = NextSolverConfig { coherence: true, globally: true };
let globally = NextSolverConfig::Globally;
let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());

// `-Zassumptions-on-binders` alone enables the next solver globally.
Expand All @@ -957,18 +957,6 @@ fn test_assumptions_on_binders_enables_next_solver_globally() {
assert!(opts.unstable_opts.assumptions_on_binders);
assert_eq!(opts.unstable_opts.next_solver, globally);

// Flag order must not matter when both `-Zassumptions-on-binders` and `-Znext-solver`
// are present.
for args in [
["-Zassumptions-on-binders".to_string(), "-Znext-solver=coherence".to_string()],
["-Znext-solver=coherence".to_string(), "-Zassumptions-on-binders".to_string()],
] {
let matches = optgroups().parse(&args).unwrap();
let opts = build_session_options(&mut early_dcx, &matches);
assert!(opts.unstable_opts.assumptions_on_binders);
assert_eq!(opts.unstable_opts.next_solver, globally);
}

// `-Zassumptions-on-binders` overrides `-Znext-solver=no` regardless of order, since
// the assumptions implementation requires the next solver. This also emits an early
// warning (covered by the UI test `next-solver-no-overridden`).
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use rustc_index::IndexVec;
use rustc_lint_defs::Lint;
use rustc_lint_defs::builtin::UNUSED_FEATURES;
use rustc_macros::Diagnostic;
use rustc_session::config::NextSolverConfig;
use rustc_session::{IncrCompSession, Session};
use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym};
Expand Down Expand Up @@ -2816,11 +2817,8 @@ impl<'tcx> TyCtxt<'tcx> {
}

pub fn next_trait_solver_globally(self) -> bool {
self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs()
}

pub fn next_trait_solver_in_coherence(self) -> bool {
self.sess.opts.unstable_opts.next_solver.coherence
self.sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally
&& !self.features().generic_const_exprs()
}

pub fn disable_trait_solver_fast_paths(self) -> bool {
Expand Down
Loading
Loading