Skip to content
Merged
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
6 changes: 6 additions & 0 deletions compiler/rustc_abi/src/canon_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub enum CanonAbi {
/// An ABI that rustc does not know how to call or define.
Custom,

/// Swift calling convention, exposed via LLVM's `swiftcc`. Cross-platform
/// and not tied to a specific target architecture.
Swift,

/// ABIs relevant to 32-bit Arm targets
Arm(ArmCall),
/// ABI relevant to GPUs: the entry point for a GPU kernel
Expand All @@ -58,6 +62,7 @@ impl CanonAbi {
CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::RustPreserveNone => true,
CanonAbi::C
| CanonAbi::Custom
| CanonAbi::Swift
| CanonAbi::Arm(_)
| CanonAbi::GpuKernel
| CanonAbi::Interrupt(_)
Expand All @@ -77,6 +82,7 @@ impl fmt::Display for CanonAbi {
CanonAbi::RustCold => ExternAbi::RustCold,
CanonAbi::RustPreserveNone => ExternAbi::RustPreserveNone,
CanonAbi::Custom => ExternAbi::Custom,
CanonAbi::Swift => ExternAbi::Swift,
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false },
ArmCall::CCmseNonSecureCall => ExternAbi::CmseNonSecureCall,
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_abi/src/extern_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ pub enum ExternAbi {
/// and only valid on platforms that have a UEFI standard
EfiApi,

/// Swift's calling convention, used to interoperate with Swift code without
/// going through C as an intermediary.
Swift,

/* arm */
/// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this
Aapcs {
Expand Down Expand Up @@ -173,6 +177,7 @@ abi_impls! {
C { unwind: false } =><= "C",
C { unwind: true } =><= "C-unwind",
Rust =><= "Rust",
Swift =><= "Swift",
Aapcs { unwind: false } =><= "aapcs",
Aapcs { unwind: true } =><= "aapcs-unwind",
AvrInterrupt =><= "avr-interrupt",
Expand Down Expand Up @@ -348,7 +353,8 @@ impl ExternAbi {
| Self::Vectorcall { .. }
| Self::SysV64 { .. }
| Self::Win64 { .. }
| Self::RustPreserveNone => true,
| Self::RustPreserveNone
| Self::Swift => true,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_lowering/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,8 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
ExternAbi::Custom => {
Err(UnstableAbi { abi, feature: sym::abi_custom, explain: GateReason::Experimental })
}
ExternAbi::Swift => {
Err(UnstableAbi { abi, feature: sym::abi_swift, explain: GateReason::Experimental })
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ impl<'a> AstValidator<'a> {
| CanonAbi::Rust
| CanonAbi::RustCold
| CanonAbi::RustPreserveNone
| CanonAbi::Swift
| CanonAbi::Arm(_)
| CanonAbi::X86(_) => { /* nothing to check */ }

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub(crate) fn conv_to_call_conv(
_ => default_call_conv,
},

CanonAbi::Interrupt(_) | CanonAbi::Arm(_) => {
CanonAbi::Interrupt(_) | CanonAbi::Arm(_) | CanonAbi::Swift => {
sess.dcx().fatal("call conv {c:?} is not yet implemented")
}
CanonAbi::GpuKernel => {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option<FnAttri
// possible to declare an `extern "custom"` block, so the backend still needs a calling
// convention for declaring foreign functions.
CanonAbi::Custom => return None,
// gcc/gccjit does not have anything for Swift's calling convention.
CanonAbi::Swift => panic!("gcc/gccjit backend does not support Swift calling convention"),
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::CCmseNonSecureCall => FnAttribute::ArmCmseNonsecureCall,
ArmCall::CCmseNonSecureEntry => FnAttribute::ArmCmseNonsecureEntry,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm:
// possible to declare an `extern "custom"` block, so the backend still needs a calling
// convention for declaring foreign functions.
CanonAbi::Custom => llvm::CCallConv,
CanonAbi::Swift => llvm::SwiftCallConv,
CanonAbi::GpuKernel => match &sess.target.arch {
Arch::AmdGpu => llvm::AmdgpuKernel,
Arch::Nvptx64 => llvm::PtxKernel,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ pub(crate) enum CallConv {
ColdCallConv = 9,
PreserveMost = 14,
PreserveAll = 15,
SwiftCallConv = 16,
Tail = 18,
PreserveNone = 21,
X86StdcallCallConv = 64,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ declare_features! (
(unstable, abi_ptx, "1.15.0", Some(38788)),
/// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
(unstable, abi_riscv_interrupt, "1.73.0", Some(111889)),
/// Allows `extern "Swift" fn()`.
(unstable, abi_swift, "CURRENT_RUSTC_VERSION", Some(156481)),
/// Allows `extern "x86-interrupt" fn()`.
(unstable, abi_x86_interrupt, "1.17.0", Some(40180)),
/// Allows additional const parameter types, such as `[u8; 10]` or user defined types
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| CanonAbi::Rust
| CanonAbi::RustCold
| CanonAbi::RustPreserveNone
| CanonAbi::Swift
| CanonAbi::Arm(_)
| CanonAbi::X86(_) => {}
}
Expand Down
19 changes: 7 additions & 12 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,33 +83,28 @@ impl LintLevelSets {
aux: Option<&FxIndexMap<LintId, LevelAndSource>>,
sess: &Session,
) -> LevelAndSource {
let lint = LintId::of(lint);
let (level, mut src) = self.raw_lint_id_level(lint, idx, aux);
let (level, lint_id) = reveal_actual_level(level, &mut src, sess, lint, |id| {
self.raw_lint_id_level(id, idx, aux)
});
LevelAndSource { level, lint_id, src }
reveal_actual_level(sess, LintId::of(lint), |id| self.raw_lint_id_level(id, idx, aux))
}

fn raw_lint_id_level(
&self,
id: LintId,
mut idx: LintStackIndex,
aux: Option<&FxIndexMap<LintId, LevelAndSource>>,
) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
) -> Option<LevelAndSource> {
if let Some(specs) = aux
&& let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id)
&& let Some(level) = specs.get(&id)
{
return (Some((level, lint_id)), src);
return Some(*level);
}

loop {
let LintSet { ref specs, parent } = self.list[idx];
if let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) {
return (Some((level, lint_id)), src);
if let Some(level) = specs.get(&id) {
return Some(*level);
}
if idx == COMMAND_LINE {
return (None, LintLevelSource::Default);
return None;
}
idx = parent;
}
Expand Down
62 changes: 27 additions & 35 deletions compiler/rustc_middle/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,29 @@ pub struct ShallowLintLevelMap {
pub specs: SortedMap<ItemLocalId, FxIndexMap<LintId, LevelAndSource>>,
}

/// From an initial level and source, verify the effect of special annotations:
/// `warnings` lint level and lint caps.
/// Verify the effect of special annotations: `warnings` lint level and lint caps.
///
/// The return of this function is suitable for diagnostics.
pub fn reveal_actual_level(
level: Option<(Level, Option<LintExpectationId>)>,
src: &mut LintLevelSource,
sess: &Session,
lint: LintId,
probe_for_lint_level: impl FnOnce(
LintId,
)
-> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource),
) -> (Level, Option<LintExpectationId>) {
probe_for_lint_level: impl Fn(LintId) -> Option<LevelAndSource>,
) -> LevelAndSource {
let level = probe_for_lint_level(lint);

// If `level` is none then we actually assume the default level for this lint.
let (mut level, mut lint_id) =
level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None));
let mut level = level.unwrap_or_else(|| LevelAndSource {
level: lint.lint.default_level(sess.edition()),
lint_id: None,
src: LintLevelSource::Default,
});

// If we're about to issue a warning, check at the last minute for any
// directives against the `warnings` lint group. If, for example, there's an
// `allow(warnings)` in scope then we want to respect that instead.
if level == Level::Warn {
let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
if let Some((configured_warning_level, configured_lint_id)) = warnings_level {
let respect_warnings_lint_group = match configured_warning_level {
if level.level == Level::Warn {
if let Some(configured_level) = probe_for_lint_level(LintId::of(builtin::WARNINGS)) {
let respect_warnings_lint_group = match configured_level.level {
// -Wwarnings is a no-op.
Level::Warn => false,
// Some warnings cannot be denied from the `warnings` lint group, only individually.
Expand All @@ -107,33 +105,31 @@ pub fn reveal_actual_level(
Level::Expect => true,
Level::ForceWarn => {
sess.dcx().span_delayed_bug(
warnings_src.span(),
configured_level.src.span(),
"cannot --force-warn the `warnings` lint group",
);
false
}
};
if respect_warnings_lint_group {
level = configured_warning_level;
lint_id = configured_lint_id;
*src = warnings_src;
level = configured_level;
}
}
}

// Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn
level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = src {
level
level.level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = level.src {
level.level
} else {
cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
cmp::min(level.level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
};

if let Some(driver_level) = sess.driver_lint_caps.get(&lint) {
// Ensure that we never exceed driver level.
level = cmp::min(*driver_level, level);
level.level = cmp::min(level.level, *driver_level);
}

(level, lint_id)
level
}

impl ShallowLintLevelMap {
Expand All @@ -146,11 +142,11 @@ impl ShallowLintLevelMap {
tcx: TyCtxt<'_>,
id: LintId,
start: HirId,
) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
) -> Option<LevelAndSource> {
if let Some(map) = self.specs.get(&start.local_id)
&& let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
&& let Some(level) = map.get(&id)
{
return (Some((level, lint_id)), src);
return Some(*level);
}

let mut owner = start.owner;
Expand All @@ -162,13 +158,13 @@ impl ShallowLintLevelMap {
specs = &tcx.shallow_lint_levels_on(owner).specs;
}
if let Some(map) = specs.get(&parent.local_id)
&& let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
&& let Some(level) = map.get(&id)
{
return (Some((level, lint_id)), src);
return Some(*level);
}
}

(None, LintLevelSource::Default)
None
}

/// Fetch and return the user-visible lint level for the given lint at the given HirId.
Expand All @@ -179,11 +175,7 @@ impl ShallowLintLevelMap {
lint: LintId,
cur: HirId,
) -> LevelAndSource {
let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur);
let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
self.probe_for_lint_level(tcx, lint, cur)
});
LevelAndSource { level, lint_id, src }
reveal_actual_level(tcx.sess, lint, |lint| self.probe_for_lint_level(tcx, lint, cur))
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
| RiscvInterruptM
| RiscvInterruptS
| RustInvalid
| Swift
| Unadjusted => false,
Rust | RustCall | RustCold | RustPreserveNone => tcx.sess.panic_strategy().unwinds(),
}
Expand Down
Loading
Loading