diff options
| author | Ben Kimock <kimockb@gmail.com> | 2025-08-10 01:45:38 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-10 01:45:38 +0000 |
| commit | 85c8d7089035d60c63a0594b07ff48981399f2ed (patch) | |
| tree | f126cf7695965577ab96b9c27e5a9c5c491f8dd2 /compiler/rustc_codegen_ssa/src | |
| parent | ee1b237215ee90df2c0102457fa2d0e9c2df8753 (diff) | |
| parent | 6e83b592cddec5ab61f1e4307134fd8f4069351e (diff) | |
| download | rust-85c8d7089035d60c63a0594b07ff48981399f2ed.tar.gz rust-85c8d7089035d60c63a0594b07ff48981399f2ed.zip | |
Merge pull request #4518 from rust-lang/rustup-2025-08-09
Automatic Rustup
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/assert_module_sources.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/apple.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/linker.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/errors.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 82 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/operand.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/target_features.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/builder.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs | 5 |
12 files changed, 144 insertions, 71 deletions
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 3710625ac12..43e1e135a66 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -69,6 +69,15 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr set_reuse(&mut ams.cgu_reuse_tracker); + if tcx.sess.opts.unstable_opts.print_mono_items + && let Some(data) = &ams.cgu_reuse_tracker.data + { + data.actual_reuse.items().all(|(cgu, reuse)| { + println!("CGU_REUSE {cgu} {reuse}"); + true + }); + } + ams.cgu_reuse_tracker.check_expected_reuse(tcx.sess); }); } diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs index d242efaf4fd..2f68bad1695 100644 --- a/compiler/rustc_codegen_ssa/src/back/apple.rs +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -17,7 +17,7 @@ mod tests; /// The canonical name of the desired SDK for a given target. pub(super) fn sdk_name(target: &Target) -> &'static str { - match (&*target.os, &*target.abi) { + match (&*target.os, &*target.env) { ("macos", "") => "MacOSX", ("ios", "") => "iPhoneOS", ("ios", "sim") => "iPhoneSimulator", @@ -34,7 +34,7 @@ pub(super) fn sdk_name(target: &Target) -> &'static str { } pub(super) fn macho_platform(target: &Target) -> u32 { - match (&*target.os, &*target.abi) { + match (&*target.os, &*target.env) { ("macos", _) => object::macho::PLATFORM_MACOS, ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST, ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b69fbf61185..6e21f54587f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3026,7 +3026,7 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool /// We need to communicate five things to the linker on Apple/Darwin targets: /// - The architecture. /// - The operating system (and that it's an Apple platform). -/// - The environment / ABI. +/// - The environment. /// - The deployment target. /// - The SDK version. fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { @@ -3040,7 +3040,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // `sess.target.arch` (`target_arch`) is not detailed enough. let llvm_arch = sess.target.llvm_target.split_once('-').expect("LLVM target must have arch").0; let target_os = &*sess.target.os; - let target_abi = &*sess.target.abi; + let target_env = &*sess.target.env; // The architecture name to forward to the linker. // @@ -3091,14 +3091,14 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // > - visionos-simulator // > - xros-simulator // > - driverkit - let platform_name = match (target_os, target_abi) { + let platform_name = match (target_os, target_env) { (os, "") => os, ("ios", "macabi") => "mac-catalyst", ("ios", "sim") => "ios-simulator", ("tvos", "sim") => "tvos-simulator", ("watchos", "sim") => "watchos-simulator", ("visionos", "sim") => "visionos-simulator", - _ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"), + _ => bug!("invalid OS/env combination for Apple target: {target_os}, {target_env}"), }; let min_version = sess.apple_deployment_target().fmt_full().to_string(); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 050797354b4..df1e91b12f9 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1805,11 +1805,18 @@ pub(crate) fn exported_symbols( .collect(); } - if let CrateType::ProcMacro = crate_type { + let mut symbols = if let CrateType::ProcMacro = crate_type { exported_symbols_for_proc_macro_crate(tcx) } else { exported_symbols_for_non_proc_macro(tcx, crate_type) + }; + + if crate_type == CrateType::Dylib || crate_type == CrateType::ProcMacro { + let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); + symbols.push((metadata_symbol_name, SymbolExportKind::Data)); } + + symbols } fn exported_symbols_for_non_proc_macro( @@ -1842,12 +1849,8 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, Symbol let stable_crate_id = tcx.stable_crate_id(LOCAL_CRATE); let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id); - let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); - vec![ - (proc_macro_decls_name, SymbolExportKind::Data), - (metadata_symbol_name, SymbolExportKind::Data), - ] + vec![(proc_macro_decls_name, SymbolExportKind::Data)] } pub(crate) fn linked_symbols( diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 4b4b39f5353..7e124f65324 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -8,7 +8,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{ - ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, metadata_symbol_name, + ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, }; use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; @@ -289,23 +289,6 @@ fn exported_non_generic_symbols_provider_local<'tcx>( })); } - if tcx.crate_types().contains(&CrateType::Dylib) - || tcx.crate_types().contains(&CrateType::ProcMacro) - { - let symbol_name = metadata_symbol_name(tcx); - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); - - symbols.push(( - exported_symbol, - SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: true, - rustc_std_internal_symbol: false, - }, - )); - } - // Sort so we get a stable incr. comp. hash. symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx)); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 3d787d8bdbd..af4adcd1954 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -764,6 +764,14 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, + #[diag(codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type, code = E0511)] + BasicIntegerOrPtrType { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = E0511)] BasicFloatType { #[primary_span] diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index fc95f62b4a4..3c667b8e882 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -92,6 +92,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let invalid_monomorphization_int_type = |ty| { bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); }; + let invalid_monomorphization_int_or_ptr_type = |ty| { + bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerOrPtrType { + span, + name, + ty, + }); + }; let parse_atomic_ordering = |ord: ty::Value<'tcx>| { let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); @@ -351,7 +358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::atomic_load => { let ty = fn_args.type_at(0); if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { - invalid_monomorphization_int_type(ty); + invalid_monomorphization_int_or_ptr_type(ty); return Ok(()); } let ordering = fn_args.const_at(1).to_value(); @@ -367,7 +374,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::atomic_store => { let ty = fn_args.type_at(0); if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { - invalid_monomorphization_int_type(ty); + invalid_monomorphization_int_or_ptr_type(ty); return Ok(()); } let ordering = fn_args.const_at(1).to_value(); @@ -377,10 +384,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.atomic_store(val, ptr, parse_atomic_ordering(ordering), size); return Ok(()); } + // These are all AtomicRMW ops sym::atomic_cxchg | sym::atomic_cxchgweak => { let ty = fn_args.type_at(0); if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { - invalid_monomorphization_int_type(ty); + invalid_monomorphization_int_or_ptr_type(ty); return Ok(()); } let succ_ordering = fn_args.const_at(1).to_value(); @@ -407,7 +415,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return Ok(()); } - // These are all AtomicRMW ops sym::atomic_max | sym::atomic_min => { let atom_op = if name == sym::atomic_max { AtomicRmwBinOp::AtomicMax @@ -420,7 +427,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ordering = fn_args.const_at(1).to_value(); let ptr = args[0].immediate(); let val = args[1].immediate(); - bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering)) + bx.atomic_rmw( + atom_op, + ptr, + val, + parse_atomic_ordering(ordering), + /* ret_ptr */ false, + ) } else { invalid_monomorphization_int_type(ty); return Ok(()); @@ -438,21 +451,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ordering = fn_args.const_at(1).to_value(); let ptr = args[0].immediate(); let val = args[1].immediate(); - bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering)) + bx.atomic_rmw( + atom_op, + ptr, + val, + parse_atomic_ordering(ordering), + /* ret_ptr */ false, + ) } else { invalid_monomorphization_int_type(ty); return Ok(()); } } - sym::atomic_xchg - | sym::atomic_xadd + sym::atomic_xchg => { + let ty = fn_args.type_at(0); + let ordering = fn_args.const_at(1).to_value(); + if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { + let ptr = args[0].immediate(); + let val = args[1].immediate(); + let atomic_op = AtomicRmwBinOp::AtomicXchg; + bx.atomic_rmw( + atomic_op, + ptr, + val, + parse_atomic_ordering(ordering), + /* ret_ptr */ ty.is_raw_ptr(), + ) + } else { + invalid_monomorphization_int_or_ptr_type(ty); + return Ok(()); + } + } + sym::atomic_xadd | sym::atomic_xsub | sym::atomic_and | sym::atomic_nand | sym::atomic_or | sym::atomic_xor => { let atom_op = match name { - sym::atomic_xchg => AtomicRmwBinOp::AtomicXchg, sym::atomic_xadd => AtomicRmwBinOp::AtomicAdd, sym::atomic_xsub => AtomicRmwBinOp::AtomicSub, sym::atomic_and => AtomicRmwBinOp::AtomicAnd, @@ -462,14 +498,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => unreachable!(), }; - let ty = fn_args.type_at(0); - if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { - let ordering = fn_args.const_at(1).to_value(); - let ptr = args[0].immediate(); - let val = args[1].immediate(); - bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering)) + // The type of the in-memory data. + let ty_mem = fn_args.type_at(0); + // The type of the 2nd operand, given by-value. + let ty_op = fn_args.type_at(1); + + let ordering = fn_args.const_at(2).to_value(); + // We require either both arguments to have the same integer type, or the first to + // be a pointer and the second to be `usize`. + if (int_type_width_signed(ty_mem, bx.tcx()).is_some() && ty_op == ty_mem) + || (ty_mem.is_raw_ptr() && ty_op == bx.tcx().types.usize) + { + let ptr = args[0].immediate(); // of type "pointer to `ty_mem`" + let val = args[1].immediate(); // of type `ty_op` + bx.atomic_rmw( + atom_op, + ptr, + val, + parse_atomic_ordering(ordering), + /* ret_ptr */ ty_mem.is_raw_ptr(), + ) } else { - invalid_monomorphization_int_type(ty); + invalid_monomorphization_int_or_ptr_type(ty_mem); return Ok(()); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 50d0f910744..06873313e2e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -296,10 +296,6 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Apply debuginfo to the newly allocated locals. fx.debug_introduce_locals(&mut start_bx, consts_debug_info.unwrap_or_default()); - // If the backend supports coverage, and coverage is enabled for this function, - // do any necessary start-of-function codegen (e.g. locals for MC/DC bitmaps). - start_bx.init_coverage(instance); - // The builders will be created separately for each basic block at `codegen_block`. // So drop the builder of `start_llbb` to avoid having two at the same time. drop(start_bx); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 5459f95c186..d851c332980 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -498,6 +498,35 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64); (is_niche, tagged_discr, 0) } else { + // Thanks to parameter attributes and load metadata, LLVM already knows + // the general valid range of the tag. It's possible, though, for there + // to be an impossible value *in the middle*, which those ranges don't + // communicate, so it's worth an `assume` to let the optimizer know. + // Most importantly, this means when optimizing a variant test like + // `SELECT(is_niche, complex, CONST) == CONST` it's ok to simplify that + // to `!is_niche` because the `complex` part can't possibly match. + // + // This was previously asserted on `tagged_discr` below, where the + // impossible value is more obvious, but that caused an intermediate + // value to become multi-use and thus not optimize, so instead this + // assumes on the original input which is always multi-use. See + // <https://github.com/llvm/llvm-project/issues/134024#issuecomment-3131782555> + // + // FIXME: If we ever get range assume operand bundles in LLVM (so we + // don't need the `icmp`s in the instruction stream any more), it + // might be worth moving this back to being on the switch argument + // where it's more obviously applicable. + if niche_variants.contains(&untagged_variant) + && bx.cx().sess().opts.optimize != OptLevel::No + { + let impossible = niche_start + .wrapping_add(u128::from(untagged_variant.as_u32())) + .wrapping_sub(u128::from(niche_variants.start().as_u32())); + let impossible = bx.cx().const_uint_big(tag_llty, impossible); + let ne = bx.icmp(IntPredicate::IntNE, tag, impossible); + bx.assume(ne); + } + // With multiple niched variants we'll have to actually compute // the variant index from the stored tag. // @@ -588,20 +617,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let untagged_variant_const = bx.cx().const_uint(cast_to, u64::from(untagged_variant.as_u32())); - // Thanks to parameter attributes and load metadata, LLVM already knows - // the general valid range of the tag. It's possible, though, for there - // to be an impossible value *in the middle*, which those ranges don't - // communicate, so it's worth an `assume` to let the optimizer know. - // Most importantly, this means when optimizing a variant test like - // `SELECT(is_niche, complex, CONST) == CONST` it's ok to simplify that - // to `!is_niche` because the `complex` part can't possibly match. - if niche_variants.contains(&untagged_variant) - && bx.cx().sess().opts.optimize != OptLevel::No - { - let ne = bx.icmp(IntPredicate::IntNE, tagged_discr, untagged_variant_const); - bx.assume(ne); - } - let discr = bx.select(is_niche, tagged_discr, untagged_variant_const); // In principle we could insert assumes on the possible range of `discr`, but diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index d984156c674..7e4341a8236 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -197,7 +197,10 @@ fn parse_rust_feature_flag<'a>( /// 2nd component of the return value, respectively). /// /// `target_base_has_feature` should check whether the given feature (a Rust feature name!) is -/// enabled in the "base" target machine, i.e., without applying `-Ctarget-feature`. +/// enabled in the "base" target machine, i.e., without applying `-Ctarget-feature`. Note that LLVM +/// may consider features to be implied that we do not and vice-versa. We want `cfg` to be entirely +/// consistent with Rust feature implications, and thus only consult LLVM to expand the target CPU +/// to target features. /// /// We do not have to worry about RUSTC_SPECIFIC_FEATURES here, those are handled elsewhere. pub fn cfg_target_feature( @@ -211,7 +214,15 @@ pub fn cfg_target_feature( .rust_target_features() .iter() .filter(|(feature, _, _)| target_base_has_feature(feature)) - .map(|(feature, _, _)| Symbol::intern(feature)) + .flat_map(|(base_feature, _, _)| { + // Expand the direct base feature into all transitively-implied features. Note that we + // cannot simply use the `implied` field of the tuple since that only contains + // directly-implied features. + // + // Iteration order is irrelevant because we're collecting into an `UnordSet`. + #[allow(rustc::potential_query_instability)] + sess.target.implied_target_features(base_feature).into_iter().map(|f| Symbol::intern(f)) + }) .collect(); // Add enabled and remove disabled features. diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 4b18146863b..f417d1a7bf7 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -548,12 +548,15 @@ pub trait BuilderMethods<'a, 'tcx>: failure_order: AtomicOrdering, weak: bool, ) -> (Self::Value, Self::Value); + /// `ret_ptr` indicates whether the return type (which is also the type `dst` points to) + /// is a pointer or the same type as `src`. fn atomic_rmw( &mut self, op: AtomicRmwBinOp, dst: Self::Value, src: Self::Value, order: AtomicOrdering, + ret_ptr: bool, ) -> Self::Value; fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope); fn set_invariant_load(&mut self, load: Self::Value); diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index 0b513dac503..31482a53b6d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -2,11 +2,6 @@ use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::ty::Instance; pub trait CoverageInfoBuilderMethods<'tcx> { - /// Performs any start-of-function codegen needed for coverage instrumentation. - /// - /// Can be a no-op in backends that don't support coverage instrumentation. - fn init_coverage(&mut self, _instance: Instance<'tcx>) {} - /// Handle the MIR coverage info in a backend-specific way. /// /// This can potentially be a no-op in backends that don't support |
