mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Auto merge of #156546 - JonathanBrouwer:rollup-5MJf3XL, r=JonathanBrouwer
Rollup of 4 pull requests Successful merges: - rust-lang/rust#155815 (Add Swift function call ABI) - rust-lang/rust#156425 (Fix unused assignments in diverging branches) - rust-lang/rust#156536 (`reveal_actual_level` improvements) - rust-lang/rust#156543 (Update rustbook dependencies to remove windows-targets dependency)
This commit is contained in:
@@ -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
|
||||
@@ -58,6 +62,7 @@ pub fn is_rustic_abi(self) -> bool {
|
||||
CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::RustPreserveNone => true,
|
||||
CanonAbi::C
|
||||
| CanonAbi::Custom
|
||||
| CanonAbi::Swift
|
||||
| CanonAbi::Arm(_)
|
||||
| CanonAbi::GpuKernel
|
||||
| CanonAbi::Interrupt(_)
|
||||
@@ -77,6 +82,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
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,
|
||||
|
||||
@@ -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 {
|
||||
@@ -173,6 +177,7 @@ fn from_str(s: &str) -> Result<$e_name, Self::Err> {
|
||||
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",
|
||||
@@ -348,7 +353,8 @@ pub fn supports_guaranteed_tail_call(self) -> bool {
|
||||
| Self::Vectorcall { .. }
|
||||
| Self::SysV64 { .. }
|
||||
| Self::Win64 { .. }
|
||||
| Self::RustPreserveNone => true,
|
||||
| Self::RustPreserveNone
|
||||
| Self::Swift => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,6 +424,7 @@ fn check_extern_fn_signature(&self, abi: ExternAbi, ctxt: FnCtxt, ident: &Ident,
|
||||
| CanonAbi::Rust
|
||||
| CanonAbi::RustCold
|
||||
| CanonAbi::RustPreserveNone
|
||||
| CanonAbi::Swift
|
||||
| CanonAbi::Arm(_)
|
||||
| CanonAbi::X86(_) => { /* nothing to check */ }
|
||||
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -166,6 +166,7 @@ pub(crate) enum CallConv {
|
||||
ColdCallConv = 9,
|
||||
PreserveMost = 14,
|
||||
PreserveAll = 15,
|
||||
SwiftCallConv = 16,
|
||||
Tail = 18,
|
||||
PreserveNone = 21,
|
||||
X86StdcallCallConv = 64,
|
||||
|
||||
@@ -380,6 +380,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
(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
|
||||
|
||||
@@ -202,6 +202,7 @@ pub(crate) fn check_call_abi(&self, abi: ExternAbi, span: Span) {
|
||||
| CanonAbi::Rust
|
||||
| CanonAbi::RustCold
|
||||
| CanonAbi::RustPreserveNone
|
||||
| CanonAbi::Swift
|
||||
| CanonAbi::Arm(_)
|
||||
| CanonAbi::X86(_) => {}
|
||||
}
|
||||
|
||||
@@ -83,12 +83,7 @@ fn get_lint_level(
|
||||
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(
|
||||
@@ -96,20 +91,20 @@ fn raw_lint_id_level(
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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 {
|
||||
@@ -146,11 +142,11 @@ fn probe_for_lint_level(
|
||||
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;
|
||||
@@ -162,13 +158,13 @@ fn probe_for_lint_level(
|
||||
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.
|
||||
@@ -179,11 +175,7 @@ pub fn lint_level_id_at_node(
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ enum CaptureKind {
|
||||
struct Access {
|
||||
/// Describe the current access.
|
||||
kind: AccessKind,
|
||||
/// MIR location where this access happens.
|
||||
location: Location,
|
||||
/// Is the accessed place is live at the current statement?
|
||||
/// When we encounter multiple statements at the same location, we only increase the liveness,
|
||||
/// in order to avoid false positives.
|
||||
@@ -648,26 +650,30 @@ fn find_dead_assignments(
|
||||
&checked_places.places,
|
||||
);
|
||||
|
||||
let mut check_place =
|
||||
|place: Place<'tcx>, kind, source_info: SourceInfo, live: &DenseBitSet<PlaceIndex>| {
|
||||
if let Some((index, extra_projections)) = checked_places.get(place.as_ref()) {
|
||||
if !is_indirect(extra_projections) {
|
||||
let is_direct = extra_projections.is_empty();
|
||||
match assignments[index].entry(source_info) {
|
||||
IndexEntry::Vacant(v) => {
|
||||
let access = Access { kind, live: live.contains(index), is_direct };
|
||||
v.insert(access);
|
||||
}
|
||||
IndexEntry::Occupied(mut o) => {
|
||||
// There were already a sighting. Mark this statement as live if it
|
||||
// was, to avoid false positives.
|
||||
o.get_mut().live |= live.contains(index);
|
||||
o.get_mut().is_direct &= is_direct;
|
||||
}
|
||||
let mut check_place = |place: Place<'tcx>,
|
||||
kind,
|
||||
source_info: SourceInfo,
|
||||
location: Location,
|
||||
live: &DenseBitSet<PlaceIndex>| {
|
||||
if let Some((index, extra_projections)) = checked_places.get(place.as_ref()) {
|
||||
if !is_indirect(extra_projections) {
|
||||
let is_direct = extra_projections.is_empty();
|
||||
match assignments[index].entry(source_info) {
|
||||
IndexEntry::Vacant(v) => {
|
||||
let access =
|
||||
Access { kind, location, live: live.contains(index), is_direct };
|
||||
v.insert(access);
|
||||
}
|
||||
IndexEntry::Occupied(mut o) => {
|
||||
// There were already a sighting. Mark this statement as live if it
|
||||
// was, to avoid false positives.
|
||||
o.get_mut().live |= live.contains(index);
|
||||
o.get_mut().is_direct &= is_direct;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
let mut record_drop = |place: Place<'tcx>| {
|
||||
if let Some((index, &[])) = checked_places.get(place.as_ref()) {
|
||||
@@ -684,7 +690,13 @@ fn find_dead_assignments(
|
||||
match &terminator.kind {
|
||||
TerminatorKind::Call { destination: place, .. }
|
||||
| TerminatorKind::Yield { resume_arg: place, .. } => {
|
||||
check_place(*place, AccessKind::Assign, terminator.source_info, live);
|
||||
check_place(
|
||||
*place,
|
||||
AccessKind::Assign,
|
||||
terminator.source_info,
|
||||
body.terminator_loc(bb),
|
||||
live,
|
||||
);
|
||||
record_drop(*place)
|
||||
}
|
||||
TerminatorKind::Drop { place, .. } => record_drop(*place),
|
||||
@@ -693,7 +705,13 @@ fn find_dead_assignments(
|
||||
if let InlineAsmOperand::Out { place: Some(place), .. }
|
||||
| InlineAsmOperand::InOut { out_place: Some(place), .. } = operand
|
||||
{
|
||||
check_place(*place, AccessKind::Assign, terminator.source_info, live);
|
||||
check_place(
|
||||
*place,
|
||||
AccessKind::Assign,
|
||||
terminator.source_info,
|
||||
body.terminator_loc(bb),
|
||||
live,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -701,13 +719,20 @@ fn find_dead_assignments(
|
||||
}
|
||||
|
||||
for (statement_index, statement) in bb_data.statements.iter().enumerate().rev() {
|
||||
cursor.seek_before_primary_effect(Location { block: bb, statement_index });
|
||||
let location = Location { block: bb, statement_index };
|
||||
cursor.seek_before_primary_effect(location);
|
||||
let live = cursor.get();
|
||||
ever_live.union(live);
|
||||
match &statement.kind {
|
||||
StatementKind::Assign(box (place, _))
|
||||
| StatementKind::SetDiscriminant { box place, .. } => {
|
||||
check_place(*place, AccessKind::Assign, statement.source_info, live);
|
||||
check_place(
|
||||
*place,
|
||||
AccessKind::Assign,
|
||||
statement.source_info,
|
||||
location,
|
||||
live,
|
||||
);
|
||||
}
|
||||
StatementKind::StorageLive(_)
|
||||
| StatementKind::StorageDead(_)
|
||||
@@ -745,7 +770,12 @@ fn find_dead_assignments(
|
||||
continue;
|
||||
};
|
||||
let source_info = body.local_decls[place.local].source_info;
|
||||
let access = Access { kind, live: live.contains(index), is_direct: true };
|
||||
let access = Access {
|
||||
kind,
|
||||
location: Location::START,
|
||||
live: live.contains(index),
|
||||
is_direct: true,
|
||||
};
|
||||
assignments[index].insert(source_info, access);
|
||||
}
|
||||
}
|
||||
@@ -1098,31 +1128,34 @@ fn report_unused_assignments(self) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut next_direct_assign = None;
|
||||
let mut next_direct_assignments: Vec<(Span, Location)> = Vec::new();
|
||||
let mut dead_statements = Vec::with_capacity(statements.len());
|
||||
|
||||
for (source_info, Access { live, kind, is_direct }) in statements.into_iter() {
|
||||
let overwrite = match (kind, is_direct, next_direct_assign) {
|
||||
(AccessKind::Assign, true, Some(overwrite_span)) => {
|
||||
Some(errors::UnusedAssignOverwrite {
|
||||
for (source_info, Access { live, kind, is_direct, location }) in statements.into_iter()
|
||||
{
|
||||
let direct_assignment = kind == AccessKind::Assign && is_direct;
|
||||
let should_report = !live && (is_direct || !is_maybe_drop_guard);
|
||||
|
||||
let overwrite = if should_report && direct_assignment {
|
||||
next_direct_assignments
|
||||
.iter()
|
||||
.rfind(|(_, overwrite_location)| {
|
||||
location.is_predecessor_of(*overwrite_location, self.body)
|
||||
})
|
||||
.map(|&(overwrite_span, _)| errors::UnusedAssignOverwrite {
|
||||
assigned_span: source_info.span,
|
||||
overwrite_span,
|
||||
name,
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if kind == AccessKind::Assign && is_direct {
|
||||
next_direct_assign = Some(source_info.span);
|
||||
if direct_assignment {
|
||||
next_direct_assignments.push((source_info.span, location));
|
||||
}
|
||||
|
||||
if live {
|
||||
continue;
|
||||
}
|
||||
// If this place was dropped and has non-trivial drop,
|
||||
// skip reporting field assignments.
|
||||
if !is_direct && is_maybe_drop_guard {
|
||||
if !should_report {
|
||||
continue;
|
||||
}
|
||||
dead_statements.push((source_info, kind, is_direct, overwrite));
|
||||
|
||||
@@ -458,6 +458,8 @@ pub enum CallConvention {
|
||||
|
||||
Custom,
|
||||
|
||||
Swift,
|
||||
|
||||
// Target-specific calling conventions.
|
||||
ArmAapcs,
|
||||
CCmseNonSecureCall,
|
||||
|
||||
@@ -1169,6 +1169,7 @@ pub enum Abi {
|
||||
RustPreserveNone,
|
||||
RustInvalid,
|
||||
Custom,
|
||||
Swift,
|
||||
}
|
||||
|
||||
/// A binder represents a possibly generic type and its bound vars.
|
||||
|
||||
@@ -619,6 +619,7 @@ fn internal<'tcx>(
|
||||
Abi::RiscvInterruptS => rustc_abi::ExternAbi::RiscvInterruptS,
|
||||
Abi::RustPreserveNone => rustc_abi::ExternAbi::RustPreserveNone,
|
||||
Abi::Custom => rustc_abi::ExternAbi::Custom,
|
||||
Abi::Swift => rustc_abi::ExternAbi::Swift,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>)
|
||||
CanonAbi::RustCold => CallConvention::Cold,
|
||||
CanonAbi::RustPreserveNone => CallConvention::PreserveNone,
|
||||
CanonAbi::Custom => CallConvention::Custom,
|
||||
CanonAbi::Swift => CallConvention::Swift,
|
||||
CanonAbi::Arm(arm_call) => match arm_call {
|
||||
ArmCall::Aapcs => CallConvention::ArmAapcs,
|
||||
ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
|
||||
|
||||
@@ -1050,6 +1050,7 @@ fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>)
|
||||
ExternAbi::RiscvInterruptM => Abi::RiscvInterruptM,
|
||||
ExternAbi::RiscvInterruptS => Abi::RiscvInterruptS,
|
||||
ExternAbi::Custom => Abi::Custom,
|
||||
ExternAbi::Swift => Abi::Swift,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,6 +355,7 @@
|
||||
abi_msp430_interrupt,
|
||||
abi_ptx,
|
||||
abi_riscv_interrupt,
|
||||
abi_swift,
|
||||
abi_sysv64,
|
||||
abi_thiscall,
|
||||
abi_unadjusted,
|
||||
|
||||
@@ -65,7 +65,9 @@ pub fn from_target(target: &Target) -> Self {
|
||||
_ => ArchKind::Other,
|
||||
};
|
||||
|
||||
let os = if target.is_like_windows {
|
||||
let os = if target.is_like_darwin {
|
||||
OsKind::Apple
|
||||
} else if target.is_like_windows {
|
||||
OsKind::Windows
|
||||
} else if target.is_like_vexos {
|
||||
OsKind::VEXos
|
||||
@@ -80,6 +82,15 @@ pub fn from_target(target: &Target) -> Self {
|
||||
pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMapping {
|
||||
let AbiMap { os, arch } = *self;
|
||||
|
||||
if extern_abi == ExternAbi::Swift {
|
||||
// Per https://www.swift.org/blog/abi-stability-and-more/, Swift's ABI
|
||||
// is only stable on Apple platforms, so we reject it elsewhere.
|
||||
match os {
|
||||
OsKind::Apple => {}
|
||||
_ => return AbiMapping::Invalid,
|
||||
}
|
||||
}
|
||||
|
||||
let canon_abi = match (extern_abi, arch) {
|
||||
// infallible lowerings
|
||||
(ExternAbi::C { .. }, _) => CanonAbi::C,
|
||||
@@ -92,6 +103,8 @@ pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMap
|
||||
|
||||
(ExternAbi::Custom, _) => CanonAbi::Custom,
|
||||
|
||||
(ExternAbi::Swift, _) => CanonAbi::Swift,
|
||||
|
||||
(ExternAbi::System { .. }, ArchKind::X86)
|
||||
if os == OsKind::Windows && !has_c_varargs =>
|
||||
{
|
||||
@@ -213,6 +226,7 @@ enum ArchKind {
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
enum OsKind {
|
||||
Apple,
|
||||
Windows,
|
||||
VEXos,
|
||||
Other,
|
||||
|
||||
@@ -58,22 +58,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.4"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.10"
|
||||
version = "3.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
|
||||
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -371,7 +371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -863,7 +863,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1176,7 +1176,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1387,7 +1387,7 @@ dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1739,7 +1739,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1801,15 +1801,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
@@ -1819,71 +1810,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.13"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//@ add-minicore
|
||||
//@ needs-llvm-components: x86
|
||||
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
|
||||
//@ ignore-backends: gcc
|
||||
#![no_core]
|
||||
#![feature(no_core, lang_items, abi_swift)]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
// The Swift ABI is only stable on Apple platforms, so it must be rejected
|
||||
// on other targets even when the `abi_swift` feature gate is enabled.
|
||||
|
||||
extern "Swift" fn f() {} //~ ERROR is not a supported ABI
|
||||
|
||||
trait T {
|
||||
extern "Swift" fn m(); //~ ERROR is not a supported ABI
|
||||
|
||||
extern "Swift" fn dm() {} //~ ERROR is not a supported ABI
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl T for S {
|
||||
extern "Swift" fn m() {} //~ ERROR is not a supported ABI
|
||||
}
|
||||
|
||||
impl S {
|
||||
extern "Swift" fn im() {} //~ ERROR is not a supported ABI
|
||||
}
|
||||
|
||||
type TA = extern "Swift" fn(); //~ ERROR is not a supported ABI
|
||||
|
||||
extern "Swift" {} //~ ERROR is not a supported ABI
|
||||
@@ -0,0 +1,45 @@
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:14:8
|
||||
|
|
||||
LL | extern "Swift" fn f() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:17:12
|
||||
|
|
||||
LL | extern "Swift" fn m();
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:19:12
|
||||
|
|
||||
LL | extern "Swift" fn dm() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:24:12
|
||||
|
|
||||
LL | extern "Swift" fn m() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:28:12
|
||||
|
|
||||
LL | extern "Swift" fn im() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:31:18
|
||||
|
|
||||
LL | type TA = extern "Swift" fn();
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0570]: "Swift" is not a supported ABI for the current target
|
||||
--> $DIR/swift-abi-non-apple.rs:33:8
|
||||
|
|
||||
LL | extern "Swift" {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0570`.
|
||||
@@ -0,0 +1,33 @@
|
||||
//@ add-minicore
|
||||
//@ needs-llvm-components: aarch64
|
||||
//@ compile-flags: --target=aarch64-apple-darwin --crate-type=rlib
|
||||
//@ ignore-backends: gcc
|
||||
#![no_core]
|
||||
#![feature(no_core, lang_items)]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
// Test that the "Swift" ABI is feature-gated, and cannot be used when
|
||||
// the `abi_swift` feature gate is not used.
|
||||
|
||||
extern "Swift" fn f() {} //~ ERROR "Swift" ABI is experimental
|
||||
|
||||
trait T {
|
||||
extern "Swift" fn m(); //~ ERROR "Swift" ABI is experimental
|
||||
|
||||
extern "Swift" fn dm() {} //~ ERROR "Swift" ABI is experimental
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl T for S {
|
||||
extern "Swift" fn m() {} //~ ERROR "Swift" ABI is experimental
|
||||
}
|
||||
|
||||
impl S {
|
||||
extern "Swift" fn im() {} //~ ERROR "Swift" ABI is experimental
|
||||
}
|
||||
|
||||
type TA = extern "Swift" fn(); //~ ERROR "Swift" ABI is experimental
|
||||
|
||||
extern "Swift" {} //~ ERROR "Swift" ABI is experimental
|
||||
@@ -0,0 +1,73 @@
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:14:8
|
||||
|
|
||||
LL | extern "Swift" fn f() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:17:12
|
||||
|
|
||||
LL | extern "Swift" fn m();
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:19:12
|
||||
|
|
||||
LL | extern "Swift" fn dm() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:24:12
|
||||
|
|
||||
LL | extern "Swift" fn m() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:28:12
|
||||
|
|
||||
LL | extern "Swift" fn im() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:31:18
|
||||
|
|
||||
LL | type TA = extern "Swift" fn();
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "Swift" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-abi_swift.rs:33:8
|
||||
|
|
||||
LL | extern "Swift" {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #156481 <https://github.com/rust-lang/rust/issues/156481> for more information
|
||||
= help: add `#![feature(abi_swift)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
@@ -0,0 +1,43 @@
|
||||
//@ run-pass
|
||||
#![allow(dead_code)]
|
||||
#![warn(unused_assignments)]
|
||||
|
||||
fn diverging_else() {
|
||||
let x;
|
||||
if true {
|
||||
x = 42;
|
||||
} else {
|
||||
x = 35;
|
||||
//~^ WARN value assigned to `x` is never read
|
||||
panic!();
|
||||
}
|
||||
println!("{x}");
|
||||
}
|
||||
|
||||
fn diverging_match_arm() {
|
||||
let x;
|
||||
match true {
|
||||
false => {
|
||||
x = 35;
|
||||
//~^ WARN value assigned to `x` is never read
|
||||
panic!();
|
||||
}
|
||||
true => x = 42,
|
||||
}
|
||||
println!("{x}");
|
||||
}
|
||||
|
||||
fn real_overwrite_after_if(cond: bool) {
|
||||
let mut x;
|
||||
if cond {
|
||||
x = 35;
|
||||
//~^ WARN value assigned to `x` is never read
|
||||
} else {
|
||||
x = 42;
|
||||
//~^ WARN value assigned to `x` is never read
|
||||
}
|
||||
x = 99;
|
||||
println!("{x}");
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,41 @@
|
||||
warning: value assigned to `x` is never read
|
||||
--> $DIR/unused-assignments-diverging-branch-issue-156416.rs:10:9
|
||||
|
|
||||
LL | x = 35;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-assignments-diverging-branch-issue-156416.rs:3:9
|
||||
|
|
||||
LL | #![warn(unused_assignments)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: value assigned to `x` is never read
|
||||
--> $DIR/unused-assignments-diverging-branch-issue-156416.rs:21:13
|
||||
|
|
||||
LL | x = 35;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
warning: value assigned to `x` is never read
|
||||
--> $DIR/unused-assignments-diverging-branch-issue-156416.rs:36:9
|
||||
|
|
||||
LL | x = 42;
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
...
|
||||
LL | x = 99;
|
||||
| ------ `x` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `x` is never read
|
||||
--> $DIR/unused-assignments-diverging-branch-issue-156416.rs:33:9
|
||||
|
|
||||
LL | x = 35;
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
...
|
||||
LL | x = 99;
|
||||
| ------ `x` is overwritten here before the previous value is read
|
||||
|
||||
warning: 4 warnings emitted
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
C
|
||||
C-unwind
|
||||
Rust
|
||||
Swift
|
||||
aapcs
|
||||
aapcs-unwind
|
||||
avr-interrupt
|
||||
|
||||
Reference in New Issue
Block a user