Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 library/core/src/io/error/os_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::fmt;
/// The provided reference must point to data that is entirely constant; it must
/// not be created during runtime.
#[inline]
pub(super) unsafe fn set_functions(f: &'static OsFunctions) {
pub(super) unsafe fn set_functions(_f: &'static OsFunctions) {
// FIXME: externally implementable items may allow for weak linkage, allowing
// these methods to be overridden even when atomic pointers are not supported.
}
Expand Down
14 changes: 14 additions & 0 deletions tests/run-make/core-no-io-statics/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// This test checks that the core library of Rust can be compiled when enabling
// `--cfg no_io_statics`.

use run_make_support::{rustc, source_root};

fn main() {
rustc()
.edition("2024")
.arg("-Dwarnings")
.crate_type("rlib")
.input(source_root().join("library/core/src/lib.rs"))
.cfg("no_io_statics")
.run();
}
Loading