Skip to content

Commit 24a352c

Browse files
Auto merge of #150914 - Zalathar:rollup-gKolHZj, r=<try>
Rollup of 15 pull requests try-job: x86_64-msvc-1 try-job: i686-msvc-1 try-job: x86_64-mingw-1 try-job: test-various try-job: armhf-gnu try-job: aarch64-apple
2 parents 1b9ae9e + 27cd10c commit 24a352c

File tree

114 files changed

+1623
-617
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+1623
-617
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,6 +2517,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25172517
span,
25182518
}
25192519
}
2520+
ExprKind::Array(elements) => {
2521+
let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
2522+
let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
2523+
let def_id = self.local_def_id(anon_const.id);
2524+
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
2525+
self.lower_anon_const_to_const_arg(anon_const)
2526+
} else {
2527+
self.lower_expr_to_const_arg_direct(element)
2528+
};
2529+
&*self.arena.alloc(const_arg)
2530+
}));
2531+
let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
2532+
span: self.lower_span(expr.span),
2533+
elems: lowered_elems,
2534+
});
2535+
2536+
ConstArg {
2537+
hir_id: self.next_id(),
2538+
kind: hir::ConstArgKind::Array(array_expr),
2539+
span,
2540+
}
2541+
}
25202542
ExprKind::Underscore => ConstArg {
25212543
hir_id: self.lower_node_id(expr.id),
25222544
kind: hir::ConstArgKind::Infer(()),
@@ -2532,6 +2554,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25322554
| ExprKind::Struct(..)
25332555
| ExprKind::Call(..)
25342556
| ExprKind::Tup(..)
2557+
| ExprKind::Array(..)
25352558
)
25362559
{
25372560
return self.lower_expr_to_const_arg_direct(expr);

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ fn check_and_apply_linkage<'ll, 'tcx>(
187187
};
188188
llvm::set_linkage(g1, base::linkage_to_llvm(linkage));
189189

190+
// Normally this is done in `get_static_inner`, but when as we generate an internal global,
191+
// it will apply the dso_local to the internal global instead, so do it here, too.
192+
cx.assume_dso_local(g1, true);
193+
190194
// Declare an internal global `extern_with_linkage_foo` which
191195
// is initialized with the address of `foo`. If `foo` is
192196
// discarded during linking (for example, if `foo` has weak

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$erro
1010
1111
codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty
1212
13+
codegen_ssa_bpf_staticlib_not_supported = linking static libraries is not supported for BPF
14+
1315
codegen_ssa_cgu_not_recorded =
1416
CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded
1517

compiler/rustc_codegen_ssa/src/back/archive.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ use tracing::trace;
2222

2323
use super::metadata::{create_compressed_metadata_file, search_for_section};
2424
use crate::common;
25-
// Re-exporting for rustc_codegen_llvm::back::archive
26-
pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind};
25+
// Public for ArchiveBuilderBuilder::extract_bundled_libs
26+
pub use crate::errors::ExtractBundledLibsError;
2727
use crate::errors::{
28-
DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile,
28+
ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary,
29+
ErrorWritingDEFFile, UnknownArchiveKind,
2930
};
3031

3132
/// An item to be included in an import library.

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2075,7 +2075,7 @@ impl<'a> Linker for BpfLinker<'a> {
20752075
}
20762076

20772077
fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) {
2078-
panic!("staticlibs not supported")
2078+
self.sess.dcx().emit_fatal(errors::BpfStaticlibNotSupported)
20792079
}
20802080

20812081
fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) {

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ pub(crate) struct RlibArchiveBuildFailure {
661661
}
662662

663663
#[derive(Diagnostic)]
664-
// Public for rustc_codegen_llvm::back::archive
664+
// Public for ArchiveBuilderBuilder::extract_bundled_libs
665665
pub enum ExtractBundledLibsError<'a> {
666666
#[diag(codegen_ssa_extract_bundled_libs_open_file)]
667667
OpenFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
@@ -700,19 +700,21 @@ pub(crate) struct UnsupportedLinkSelfContained;
700700

701701
#[derive(Diagnostic)]
702702
#[diag(codegen_ssa_archive_build_failure)]
703-
// Public for rustc_codegen_llvm::back::archive
704-
pub struct ArchiveBuildFailure {
703+
pub(crate) struct ArchiveBuildFailure {
705704
pub path: PathBuf,
706705
pub error: std::io::Error,
707706
}
708707

709708
#[derive(Diagnostic)]
710709
#[diag(codegen_ssa_unknown_archive_kind)]
711-
// Public for rustc_codegen_llvm::back::archive
712-
pub struct UnknownArchiveKind<'a> {
710+
pub(crate) struct UnknownArchiveKind<'a> {
713711
pub kind: &'a str,
714712
}
715713

714+
#[derive(Diagnostic)]
715+
#[diag(codegen_ssa_bpf_staticlib_not_supported)]
716+
pub(crate) struct BpfStaticlibNotSupported;
717+
716718
#[derive(Diagnostic)]
717719
#[diag(codegen_ssa_multiple_main_functions)]
718720
#[help]

compiler/rustc_const_eval/src/check_consts/qualifs.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
// having basically only two use-cases that act in different ways.
77

88
use rustc_errors::ErrorGuaranteed;
9-
use rustc_hir::attrs::AttributeKind;
10-
use rustc_hir::def::DefKind;
11-
use rustc_hir::{LangItem, find_attr};
9+
use rustc_hir::LangItem;
1210
use rustc_infer::infer::TyCtxtInferExt;
1311
use rustc_middle::mir::*;
1412
use rustc_middle::ty::{self, AdtDef, Ty};
@@ -366,14 +364,10 @@ where
366364
// check performed after the promotion. Verify that with an assertion.
367365
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
368366

369-
// Avoid looking at attrs of anon consts as that will ICE
370-
let is_type_const_item =
371-
matches!(cx.tcx.def_kind(def), DefKind::Const | DefKind::AssocConst)
372-
&& find_attr!(cx.tcx.get_all_attrs(def), AttributeKind::TypeConst(_));
373-
374367
// Don't peak inside trait associated constants, also `#[type_const] const` items
375368
// don't have bodies so there's nothing to look at
376-
if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !is_type_const_item {
369+
if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !cx.tcx.is_type_const(def)
370+
{
377371
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def);
378372

379373
if !Q::in_qualifs(&qualifs) {

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
88
use rustc_hir::def_id::{DefId, LocalDefId};
99
use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
1010
use rustc_middle::mir::AssertMessage;
11-
use rustc_middle::mir::interpret::ReportedErrorInfo;
11+
use rustc_middle::mir::interpret::{Pointer, ReportedErrorInfo};
1212
use rustc_middle::query::TyCtxtAt;
1313
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement};
1414
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -22,7 +22,7 @@ use crate::errors::{LongRunning, LongRunningWarn};
2222
use crate::fluent_generated as fluent;
2323
use crate::interpret::{
2424
self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame,
25-
GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, RangeSet, Scalar,
25+
GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, RangeSet, Scalar,
2626
compile_time_machine, err_inval, interp_ok, throw_exhaust, throw_inval, throw_ub,
2727
throw_ub_custom, throw_unsup, throw_unsup_format,
2828
};
@@ -586,6 +586,11 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
586586
}
587587
}
588588

589+
sym::type_of => {
590+
let ty = ecx.read_type_id(&args[0])?;
591+
ecx.write_type_info(ty, dest)?;
592+
}
593+
589594
_ => {
590595
// We haven't handled the intrinsic, let's see if we can use a fallback body.
591596
if ecx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden {

compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mod error;
1313
mod eval_queries;
1414
mod fn_queries;
1515
mod machine;
16+
mod type_info;
1617
mod valtrees;
1718

1819
pub use self::dummy_machine::*;
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
use rustc_abi::FieldIdx;
2+
use rustc_hir::LangItem;
3+
use rustc_middle::mir::interpret::CtfeProvenance;
4+
use rustc_middle::span_bug;
5+
use rustc_middle::ty::layout::TyAndLayout;
6+
use rustc_middle::ty::{self, ScalarInt, Ty};
7+
use rustc_span::{Symbol, sym};
8+
9+
use crate::const_eval::CompileTimeMachine;
10+
use crate::interpret::{
11+
Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Writeable, interp_ok,
12+
};
13+
14+
impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
15+
/// Writes a `core::mem::type_info::TypeInfo` for a given type, `ty` to the given place.
16+
pub(crate) fn write_type_info(
17+
&mut self,
18+
ty: Ty<'tcx>,
19+
dest: &impl Writeable<'tcx, CtfeProvenance>,
20+
) -> InterpResult<'tcx> {
21+
let ty_struct = self.tcx.require_lang_item(LangItem::Type, self.tcx.span);
22+
let ty_struct = self.tcx.type_of(ty_struct).no_bound_vars().unwrap();
23+
assert_eq!(ty_struct, dest.layout().ty);
24+
let ty_struct = ty_struct.ty_adt_def().unwrap().non_enum_variant();
25+
// Fill all fields of the `TypeInfo` struct.
26+
for (idx, field) in ty_struct.fields.iter_enumerated() {
27+
let field_dest = self.project_field(dest, idx)?;
28+
let downcast = |name: Symbol| {
29+
let variants = field_dest.layout().ty.ty_adt_def().unwrap().variants();
30+
let variant_id = variants
31+
.iter_enumerated()
32+
.find(|(_idx, var)| var.name == name)
33+
.unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}"))
34+
.0;
35+
36+
interp_ok((variant_id, self.project_downcast(&field_dest, variant_id)?))
37+
};
38+
match field.name {
39+
sym::kind => {
40+
let variant_index = match ty.kind() {
41+
ty::Tuple(fields) => {
42+
let (variant, variant_place) = downcast(sym::Tuple)?;
43+
// project to the single tuple variant field of `type_info::Tuple` struct type
44+
let tuple_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
45+
assert_eq!(
46+
1,
47+
tuple_place
48+
.layout()
49+
.ty
50+
.ty_adt_def()
51+
.unwrap()
52+
.non_enum_variant()
53+
.fields
54+
.len()
55+
);
56+
self.write_tuple_fields(tuple_place, fields, ty)?;
57+
variant
58+
}
59+
// For now just merge all primitives into one `Leaf` variant with no data
60+
ty::Uint(_) | ty::Int(_) | ty::Float(_) | ty::Char | ty::Bool => {
61+
downcast(sym::Leaf)?.0
62+
}
63+
ty::Adt(_, _)
64+
| ty::Foreign(_)
65+
| ty::Str
66+
| ty::Array(_, _)
67+
| ty::Pat(_, _)
68+
| ty::Slice(_)
69+
| ty::RawPtr(..)
70+
| ty::Ref(..)
71+
| ty::FnDef(..)
72+
| ty::FnPtr(..)
73+
| ty::UnsafeBinder(..)
74+
| ty::Dynamic(..)
75+
| ty::Closure(..)
76+
| ty::CoroutineClosure(..)
77+
| ty::Coroutine(..)
78+
| ty::CoroutineWitness(..)
79+
| ty::Never
80+
| ty::Alias(..)
81+
| ty::Param(_)
82+
| ty::Bound(..)
83+
| ty::Placeholder(_)
84+
| ty::Infer(..)
85+
| ty::Error(_) => downcast(sym::Other)?.0,
86+
};
87+
self.write_discriminant(variant_index, &field_dest)?
88+
}
89+
sym::size => {
90+
let layout = self.layout_of(ty)?;
91+
let variant_index = if layout.is_sized() {
92+
let (variant, variant_place) = downcast(sym::Some)?;
93+
let size_field_place =
94+
self.project_field(&variant_place, FieldIdx::ZERO)?;
95+
self.write_scalar(
96+
ScalarInt::try_from_target_usize(layout.size.bytes(), self.tcx.tcx)
97+
.unwrap(),
98+
&size_field_place,
99+
)?;
100+
variant
101+
} else {
102+
downcast(sym::None)?.0
103+
};
104+
self.write_discriminant(variant_index, &field_dest)?;
105+
}
106+
other => span_bug!(self.tcx.span, "unknown `Type` field {other}"),
107+
}
108+
}
109+
110+
interp_ok(())
111+
}
112+
113+
pub(crate) fn write_tuple_fields(
114+
&mut self,
115+
tuple_place: impl Writeable<'tcx, CtfeProvenance>,
116+
fields: &[Ty<'tcx>],
117+
tuple_ty: Ty<'tcx>,
118+
) -> InterpResult<'tcx> {
119+
// project into the `type_info::Tuple::fields` field
120+
let fields_slice_place = self.project_field(&tuple_place, FieldIdx::ZERO)?;
121+
// get the `type_info::Field` type from `fields: &[Field]`
122+
let field_type = fields_slice_place
123+
.layout()
124+
.ty
125+
.builtin_deref(false)
126+
.unwrap()
127+
.sequence_element_type(self.tcx.tcx);
128+
// Create an array with as many elements as the number of fields in the inspected tuple
129+
let fields_layout =
130+
self.layout_of(Ty::new_array(self.tcx.tcx, field_type, fields.len() as u64))?;
131+
let fields_place = self.allocate(fields_layout, MemoryKind::Stack)?;
132+
let mut fields_places = self.project_array_fields(&fields_place)?;
133+
134+
let tuple_layout = self.layout_of(tuple_ty)?;
135+
136+
while let Some((i, place)) = fields_places.next(self)? {
137+
let field_ty = fields[i as usize];
138+
self.write_field(field_ty, place, tuple_layout, i)?;
139+
}
140+
141+
let fields_place = fields_place.map_provenance(CtfeProvenance::as_immutable);
142+
143+
let ptr = Immediate::new_slice(fields_place.ptr(), fields.len() as u64, self);
144+
145+
self.write_immediate(ptr, &fields_slice_place)
146+
}
147+
148+
fn write_field(
149+
&mut self,
150+
field_ty: Ty<'tcx>,
151+
place: MPlaceTy<'tcx>,
152+
layout: TyAndLayout<'tcx>,
153+
idx: u64,
154+
) -> InterpResult<'tcx> {
155+
for (field_idx, field_ty_field) in
156+
place.layout.ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
157+
{
158+
let field_place = self.project_field(&place, field_idx)?;
159+
match field_ty_field.name {
160+
sym::ty => self.write_type_id(field_ty, &field_place)?,
161+
sym::offset => {
162+
let offset = layout.fields.offset(idx as usize);
163+
self.write_scalar(
164+
ScalarInt::try_from_target_usize(offset.bytes(), self.tcx.tcx).unwrap(),
165+
&field_place,
166+
)?;
167+
}
168+
other => {
169+
span_bug!(self.tcx.def_span(field_ty_field.did), "unimplemented field {other}")
170+
}
171+
}
172+
}
173+
interp_ok(())
174+
}
175+
}

0 commit comments

Comments
 (0)