Skip to content

Commit 792fc2b

Browse files
committed
Auto merge of #141984 - matthiaskrgr:rollup-wy6j9ca, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #137725 (Add `iter` macro) - #141455 (std: abort the process on failure to allocate a TLS key) - #141569 (Replace ad-hoc ABI "adjustments" with an `AbiMap` to `CanonAbi`) - #141698 (Use the informative error as the main const eval error message) - #141925 (Remove bootstrap cfgs from library/) - #141943 (Remove pre-expansion AST stats.) - #141945 (Remove `Path::is_ident`.) - #141957 (Add missing `dyn` keywords to tests that do not test for them Part 2) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 59aa1e8 + a2b6f14 commit 792fc2b

File tree

569 files changed

+5958
-5460
lines changed

Some content is hidden

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

569 files changed

+5958
-5460
lines changed

compiler/rustc_abi/src/canon_abi.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
use std::fmt;
2+
3+
#[cfg(feature = "nightly")]
4+
use rustc_macros::HashStable_Generic;
5+
6+
use crate::ExternAbi;
7+
8+
/// Calling convention to determine codegen
9+
///
10+
/// CanonAbi erases certain distinctions ExternAbi preserves, but remains target-dependent.
11+
/// There are still both target-specific variants and aliasing variants, though much fewer.
12+
/// The reason for this step is the frontend may wish to show an ExternAbi but implement that ABI
13+
/// using a different ABI than the string per se, or describe irrelevant differences, e.g.
14+
/// - extern "system"
15+
/// - extern "cdecl"
16+
/// - extern "C-unwind"
17+
/// In that sense, this erases mere syntactic distinctions to create a canonical *directive*,
18+
/// rather than picking the "actual" ABI.
19+
#[derive(Copy, Clone, Debug)]
20+
#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]
21+
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
22+
pub enum CanonAbi {
23+
// NOTE: the use of nested variants for some ABIs is for many targets they don't matter,
24+
// and this pushes the complexity of their reasoning to target-specific code,
25+
// allowing a `match` to easily exhaustively ignore these subcategories of variants.
26+
// Otherwise it is very tempting to avoid matching exhaustively!
27+
C,
28+
Rust,
29+
RustCold,
30+
31+
/// ABIs relevant to 32-bit Arm targets
32+
Arm(ArmCall),
33+
/// ABI relevant to GPUs: the entry point for a GPU kernel
34+
GpuKernel,
35+
36+
/// ABIs relevant to bare-metal interrupt targets
37+
// FIXME(workingjubilee): a particular reason for this nesting is we might not need these?
38+
// interrupt ABIs should have the same properties:
39+
// - uncallable by Rust calls, as LLVM rejects it in most cases
40+
// - uses a preserve-all-registers *callee* convention
41+
// - should always return `-> !` (effectively... it can't use normal `ret`)
42+
// what differs between targets is
43+
// - allowed arguments: x86 differs slightly, having 2-3 arguments which are handled magically
44+
// - may need special prologues/epilogues for some interrupts, without affecting "call ABI"
45+
Interrupt(InterruptKind),
46+
47+
/// ABIs relevant to Windows or x86 targets
48+
X86(X86Call),
49+
}
50+
51+
impl fmt::Display for CanonAbi {
52+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53+
self.to_erased_extern_abi().as_str().fmt(f)
54+
}
55+
}
56+
57+
impl CanonAbi {
58+
/// convert to the ExternAbi that *shares a string* with this CanonAbi
59+
///
60+
/// A target-insensitive mapping of CanonAbi to ExternAbi, convenient for "forwarding" impls.
61+
/// Importantly, the set of CanonAbi values is a logical *subset* of ExternAbi values,
62+
/// so this is injective: if you take an ExternAbi to a CanonAbi and back, you have lost data.
63+
const fn to_erased_extern_abi(self) -> ExternAbi {
64+
match self {
65+
CanonAbi::C => ExternAbi::C { unwind: false },
66+
CanonAbi::Rust => ExternAbi::Rust,
67+
CanonAbi::RustCold => ExternAbi::RustCold,
68+
CanonAbi::Arm(arm_call) => match arm_call {
69+
ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false },
70+
ArmCall::CCmseNonSecureCall => ExternAbi::CCmseNonSecureCall,
71+
ArmCall::CCmseNonSecureEntry => ExternAbi::CCmseNonSecureEntry,
72+
},
73+
CanonAbi::GpuKernel => ExternAbi::GpuKernel,
74+
CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
75+
InterruptKind::Avr => ExternAbi::AvrInterrupt,
76+
InterruptKind::AvrNonBlocking => ExternAbi::AvrNonBlockingInterrupt,
77+
InterruptKind::Msp430 => ExternAbi::Msp430Interrupt,
78+
InterruptKind::RiscvMachine => ExternAbi::RiscvInterruptM,
79+
InterruptKind::RiscvSupervisor => ExternAbi::RiscvInterruptS,
80+
InterruptKind::X86 => ExternAbi::X86Interrupt,
81+
},
82+
CanonAbi::X86(x86_call) => match x86_call {
83+
X86Call::Fastcall => ExternAbi::Fastcall { unwind: false },
84+
X86Call::Stdcall => ExternAbi::Stdcall { unwind: false },
85+
X86Call::SysV64 => ExternAbi::SysV64 { unwind: false },
86+
X86Call::Thiscall => ExternAbi::Thiscall { unwind: false },
87+
X86Call::Vectorcall => ExternAbi::Vectorcall { unwind: false },
88+
X86Call::Win64 => ExternAbi::Win64 { unwind: false },
89+
},
90+
}
91+
}
92+
}
93+
94+
/// Callee codegen for interrupts
95+
///
96+
/// This is named differently from the "Call" enums because it is different:
97+
/// these "ABI" differences are not relevant to callers, since there is "no caller".
98+
/// These only affect callee codegen. making their categorization as distinct ABIs a bit peculiar.
99+
#[derive(Copy, Clone, Debug)]
100+
#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]
101+
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
102+
pub enum InterruptKind {
103+
Avr,
104+
AvrNonBlocking,
105+
Msp430,
106+
RiscvMachine,
107+
RiscvSupervisor,
108+
X86,
109+
}
110+
111+
/// ABIs defined for x86-{32,64}
112+
///
113+
/// One of SysV64 or Win64 may alias the C ABI, and arguably Win64 is cross-platform now?
114+
#[derive(Clone, Copy, Debug)]
115+
#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]
116+
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
117+
pub enum X86Call {
118+
/// "fastcall" has both GNU and Windows variants
119+
Fastcall,
120+
/// "stdcall" has both GNU and Windows variants
121+
Stdcall,
122+
SysV64,
123+
Thiscall,
124+
Vectorcall,
125+
Win64,
126+
}
127+
128+
/// ABIs defined for 32-bit Arm
129+
#[derive(Copy, Clone, Debug)]
130+
#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]
131+
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
132+
pub enum ArmCall {
133+
Aapcs,
134+
CCmseNonSecureCall,
135+
CCmseNonSecureEntry,
136+
}

compiler/rustc_abi/src/extern_abi.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd};
77
#[cfg(feature = "nightly")]
88
use rustc_macros::{Decodable, Encodable};
99

10+
use crate::AbiFromStrErr;
11+
1012
#[cfg(test)]
1113
mod tests;
1214

@@ -99,11 +101,6 @@ macro_rules! abi_impls {
99101
}
100102
}
101103

102-
#[derive(Debug)]
103-
pub enum AbiFromStrErr {
104-
Unknown,
105-
}
106-
107104
abi_impls! {
108105
ExternAbi = {
109106
C { unwind: false } =><= "C",

compiler/rustc_abi/src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,14 @@ use rustc_index::{Idx, IndexSlice, IndexVec};
5555
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_Generic};
5656

5757
mod callconv;
58+
mod canon_abi;
59+
mod extern_abi;
5860
mod layout;
5961
#[cfg(test)]
6062
mod tests;
6163

62-
mod extern_abi;
63-
6464
pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind};
65+
pub use canon_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
6566
pub use extern_abi::{ExternAbi, all_names};
6667
#[cfg(feature = "nightly")]
6768
pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
@@ -1895,3 +1896,11 @@ pub enum StructKind {
18951896
/// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
18961897
Prefixed(Size, Align),
18971898
}
1899+
1900+
#[derive(Clone, Debug)]
1901+
pub enum AbiFromStrErr {
1902+
/// not a known ABI
1903+
Unknown,
1904+
/// no "-unwind" variant can be used here
1905+
NoExplicitUnwind,
1906+
}

compiler/rustc_ast/src/ast.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,15 @@ pub struct Path {
9999

100100
impl PartialEq<Symbol> for Path {
101101
#[inline]
102-
fn eq(&self, symbol: &Symbol) -> bool {
103-
matches!(&self.segments[..], [segment] if segment.ident.name == *symbol)
102+
fn eq(&self, name: &Symbol) -> bool {
103+
if let [segment] = self.segments.as_ref()
104+
&& segment.args.is_none()
105+
&& segment.ident.name == *name
106+
{
107+
true
108+
} else {
109+
false
110+
}
104111
}
105112
}
106113

@@ -120,17 +127,6 @@ impl Path {
120127
Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
121128
}
122129

123-
pub fn is_ident(&self, name: Symbol) -> bool {
124-
if let [segment] = self.segments.as_ref()
125-
&& segment.args.is_none()
126-
&& segment.ident.name == name
127-
{
128-
true
129-
} else {
130-
false
131-
}
132-
}
133-
134130
pub fn is_global(&self) -> bool {
135131
self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
136132
}

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::assert_matches::assert_matches;
21
use std::ops::ControlFlow;
32
use std::sync::Arc;
43

@@ -1199,11 +1198,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
11991198
let closure_def_id = self.local_def_id(closure_id);
12001199
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
12011200

1202-
assert_matches!(
1203-
coroutine_kind,
1204-
CoroutineKind::Async { .. },
1205-
"only async closures are supported currently"
1206-
);
1201+
let coroutine_desugaring = match coroutine_kind {
1202+
CoroutineKind::Async { .. } => hir::CoroutineDesugaring::Async,
1203+
CoroutineKind::Gen { .. } => hir::CoroutineDesugaring::Gen,
1204+
CoroutineKind::AsyncGen { span, .. } => {
1205+
span_bug!(span, "only async closures and `iter!` closures are supported currently")
1206+
}
1207+
};
12071208

12081209
let body = self.with_new_scopes(fn_decl_span, |this| {
12091210
let inner_decl =
@@ -1247,7 +1248,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12471248
// Lower this as a `CoroutineClosure`. That will ensure that HIR typeck
12481249
// knows that a `FnDecl` output type like `-> &str` actually means
12491250
// "coroutine that returns &str", rather than directly returning a `&str`.
1250-
kind: hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async),
1251+
kind: hir::ClosureKind::CoroutineClosure(coroutine_desugaring),
12511252
constness: hir::Constness::NotConst,
12521253
});
12531254
hir::ExprKind::Closure(c)

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
477477
for span in spans {
478478
if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines))
479479
&& (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks))
480+
&& (!visitor.features.yield_expr() && !span.allows_unstable(sym::yield_expr))
480481
{
481482
#[allow(rustc::untranslatable_diagnostic)]
482-
// Don't know which of the two features to include in the
483-
// error message, so I am arbitrarily picking one.
484-
feature_err(&visitor.sess, sym::coroutines, *span, "yield syntax is experimental")
483+
// Emit yield_expr as the error, since that will be sufficient. You can think of it
484+
// as coroutines and gen_blocks imply yield_expr.
485+
feature_err(&visitor.sess, sym::yield_expr, *span, "yield syntax is experimental")
485486
.emit();
486487
}
487488
}

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
5252
assert_matches!(
5353
self.tcx().coroutine_kind(self.tcx().coroutine_for_closure(mir_def_id)),
5454
Some(hir::CoroutineKind::Desugared(
55-
hir::CoroutineDesugaring::Async,
55+
hir::CoroutineDesugaring::Async | hir::CoroutineDesugaring::Gen,
5656
hir::CoroutineSource::Closure
5757
)),
5858
"this needs to be modified if we're lowering non-async closures"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use rustc_ast::ptr::P;
2+
use rustc_ast::tokenstream::TokenStream;
3+
use rustc_ast::{CoroutineKind, DUMMY_NODE_ID, Expr, ast, token};
4+
use rustc_errors::PResult;
5+
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
6+
use rustc_span::Span;
7+
8+
pub(crate) fn expand<'cx>(
9+
cx: &'cx mut ExtCtxt<'_>,
10+
sp: Span,
11+
tts: TokenStream,
12+
) -> MacroExpanderResult<'cx> {
13+
let closure = match parse_closure(cx, sp, tts) {
14+
Ok(parsed) => parsed,
15+
Err(err) => {
16+
return ExpandResult::Ready(DummyResult::any(sp, err.emit()));
17+
}
18+
};
19+
20+
ExpandResult::Ready(base::MacEager::expr(closure))
21+
}
22+
23+
fn parse_closure<'a>(
24+
cx: &mut ExtCtxt<'a>,
25+
span: Span,
26+
stream: TokenStream,
27+
) -> PResult<'a, P<Expr>> {
28+
let mut closure_parser = cx.new_parser_from_tts(stream);
29+
30+
let coroutine_kind = Some(CoroutineKind::Gen {
31+
span,
32+
closure_id: DUMMY_NODE_ID,
33+
return_impl_trait_id: DUMMY_NODE_ID,
34+
});
35+
36+
let mut closure = closure_parser.parse_expr()?;
37+
match &mut closure.kind {
38+
ast::ExprKind::Closure(c) => {
39+
if let Some(kind) = c.coroutine_kind {
40+
cx.dcx().span_err(kind.span(), "only plain closures allowed in `iter!`");
41+
}
42+
c.coroutine_kind = coroutine_kind;
43+
if closure_parser.token != token::Eof {
44+
closure_parser.unexpected()?;
45+
}
46+
Ok(closure)
47+
}
48+
_ => {
49+
cx.dcx().span_err(closure.span, "`iter!` body must be a closure");
50+
Err(closure_parser.unexpected().unwrap_err())
51+
}
52+
}
53+
}

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ mod errors;
4747
mod format;
4848
mod format_foreign;
4949
mod global_allocator;
50+
mod iter;
5051
mod log_syntax;
5152
mod pattern_type;
5253
mod source_util;
@@ -95,6 +96,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
9596
include: source_util::expand_include,
9697
include_bytes: source_util::expand_include_bytes,
9798
include_str: source_util::expand_include_str,
99+
iter: iter::expand,
98100
line: source_util::expand_line,
99101
log_syntax: log_syntax::expand_log_syntax,
100102
module_path: source_util::expand_mod,

0 commit comments

Comments
 (0)