diff --git a/compiler/rustc_abi/src/canon_abi.rs b/compiler/rustc_abi/src/canon_abi.rs index 3ef3fa365298..316cb05ec180 100644 --- a/compiler/rustc_abi/src/canon_abi.rs +++ b/compiler/rustc_abi/src/canon_abi.rs @@ -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, diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index bba01ebefca8..3def8a8ccf0b 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -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, } } } diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs index 326576bb1488..00b6a353d93f 100644 --- a/compiler/rustc_ast_lowering/src/stability.rs +++ b/compiler/rustc_ast_lowering/src/stability.rs @@ -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 }) + } } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 5725c6551884..afaee6e54208 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -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 */ } diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 6a27b8172f98..a8b179f169bf 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -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 => { diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 2f5c555b702a..7239a5bcb041 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -245,6 +245,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option 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, diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index dcde960258a5..c3bf566b3588 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -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, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 573a765aef02..a240bca80955 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -166,6 +166,7 @@ pub(crate) enum CallConv { ColdCallConv = 9, PreserveMost = 14, PreserveAll = 15, + SwiftCallConv = 16, Tail = 18, PreserveNone = 21, X86StdcallCallConv = 64, diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 61354d7f3367..8385c320d377 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -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 diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index a564c57c3648..e15c9fe66164 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -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(_) => {} } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 8f68f6b8abf4..a5fe6bdfe6c5 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -83,12 +83,7 @@ fn get_lint_level( aux: Option<&FxIndexMap>, 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>, - ) -> (Option<(Level, Option)>, LintLevelSource) { + ) -> Option { 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; } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index bb293f026899..a05d24cdabad 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -71,31 +71,29 @@ pub struct ShallowLintLevelMap { pub specs: SortedMap>, } -/// 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)>, - src: &mut LintLevelSource, sess: &Session, lint: LintId, - probe_for_lint_level: impl FnOnce( - LintId, - ) - -> (Option<(Level, Option)>, LintLevelSource), -) -> (Level, Option) { + probe_for_lint_level: impl Fn(LintId) -> Option, +) -> 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)>, LintLevelSource) { + ) -> Option { 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)) } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index a658bd1061a2..e2fc66385237 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1290,6 +1290,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: ExternAbi) | RiscvInterruptM | RiscvInterruptS | RustInvalid + | Swift | Unadjusted => false, Rust | RustCall | RustCold | RustPreserveNone => tcx.sess.panic_strategy().unwinds(), } diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 95cdd8ad3e67..35f255a3f074 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -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| { - 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| { + 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)); diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 4a780d652df8..1227fe23713c 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -458,6 +458,8 @@ pub enum CallConvention { Custom, + Swift, + // Target-specific calling conventions. ArmAapcs, CCmseNonSecureCall, diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 59b4c6bee5c0..f71ca7213e9e 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -1169,6 +1169,7 @@ pub enum Abi { RustPreserveNone, RustInvalid, Custom, + Swift, } /// A binder represents a possibly generic type and its bound vars. diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs index 165ad737fccb..37f00da9f710 100644 --- a/compiler/rustc_public/src/unstable/convert/internal.rs +++ b/compiler/rustc_public/src/unstable/convert/internal.rs @@ -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, } } } diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 56fbd8108786..b98a9804ce8b 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -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, diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 80453d838b88..c4f1da14da23 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -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, } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 691051756792..69ed7314855f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -355,6 +355,7 @@ abi_msp430_interrupt, abi_ptx, abi_riscv_interrupt, + abi_swift, abi_sysv64, abi_thiscall, abi_unadjusted, diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index c0fdd946778b..8c56dcb89971 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -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, diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 941bf2829ef7..89a581c90aa8 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -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" diff --git a/tests/ui/abi/swift-abi-non-apple.rs b/tests/ui/abi/swift-abi-non-apple.rs new file mode 100644 index 000000000000..a374f38c9c8e --- /dev/null +++ b/tests/ui/abi/swift-abi-non-apple.rs @@ -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 diff --git a/tests/ui/abi/swift-abi-non-apple.stderr b/tests/ui/abi/swift-abi-non-apple.stderr new file mode 100644 index 000000000000..7dae75c96d46 --- /dev/null +++ b/tests/ui/abi/swift-abi-non-apple.stderr @@ -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`. diff --git a/tests/ui/feature-gates/feature-gate-abi_swift.rs b/tests/ui/feature-gates/feature-gate-abi_swift.rs new file mode 100644 index 000000000000..dc78d4fa33bc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-abi_swift.rs @@ -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 diff --git a/tests/ui/feature-gates/feature-gate-abi_swift.stderr b/tests/ui/feature-gates/feature-gate-abi_swift.stderr new file mode 100644 index 000000000000..0d839d95fe83 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-abi_swift.stderr @@ -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 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 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 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 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 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 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 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`. diff --git a/tests/ui/liveness/unused-assignments-diverging-branch-issue-156416.rs b/tests/ui/liveness/unused-assignments-diverging-branch-issue-156416.rs new file mode 100644 index 000000000000..08cffa00f752 --- /dev/null +++ b/tests/ui/liveness/unused-assignments-diverging-branch-issue-156416.rs @@ -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() {} diff --git a/tests/ui/liveness/unused-assignments-diverging-branch-issue-156416.stderr b/tests/ui/liveness/unused-assignments-diverging-branch-issue-156416.stderr new file mode 100644 index 000000000000..5afb33626e05 --- /dev/null +++ b/tests/ui/liveness/unused-assignments-diverging-branch-issue-156416.stderr @@ -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 + diff --git a/tests/ui/print-request/print-calling-conventions.stdout b/tests/ui/print-request/print-calling-conventions.stdout index 8366697d0fb0..506bbea23e17 100644 --- a/tests/ui/print-request/print-calling-conventions.stdout +++ b/tests/ui/print-request/print-calling-conventions.stdout @@ -1,6 +1,7 @@ C C-unwind Rust +Swift aapcs aapcs-unwind avr-interrupt