diff options
55 files changed, 818 insertions, 345 deletions
diff --git a/Cargo.lock b/Cargo.lock index 0f65cc696ab..9fa1daf6546 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4006,7 +4006,6 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_type_ir", - "snap", "tempfile", "tracing", ] @@ -4892,12 +4891,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - -[[package]] name = "socket2" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 2c5ec9dad59..64bb22e8cb2 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -232,11 +232,6 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { return None; } - // probestack doesn't play nice either with gcov profiling. - if cx.sess().opts.unstable_opts.profile { - return None; - } - let attr_value = match cx.sess().target.stack_probes { StackProbeType::None => return None, // Request LLVM to generate the probes inline. If the given LLVM version does not support diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bfa9e8b82a0..cf7b16c9cc4 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -591,7 +591,6 @@ pub(crate) unsafe fn llvm_optimize( pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), config.instrument_coverage, instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - config.instrument_gcov, pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), config.debug_info_for_profiling, llvm_selfprofiler, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 9064cfaeb29..0d1fd0163eb 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -7,7 +7,6 @@ use std::{iter, ptr}; use libc::{c_char, c_longlong, c_uint}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; -use rustc_fs_util::path_to_c_string; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; @@ -979,33 +978,8 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( debug_name_table_kind, ); - if tcx.sess.opts.unstable_opts.profile { - let default_gcda_path = &output_filenames.with_extension("gcda"); - let gcda_path = - tcx.sess.opts.unstable_opts.profile_emit.as_ref().unwrap_or(default_gcda_path); - - let gcov_cu_info = [ - path_to_mdstring(debug_context.llcontext, &output_filenames.with_extension("gcno")), - path_to_mdstring(debug_context.llcontext, gcda_path), - unit_metadata, - ]; - let gcov_metadata = llvm::LLVMMDNodeInContext2( - debug_context.llcontext, - gcov_cu_info.as_ptr(), - gcov_cu_info.len(), - ); - let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata); - - llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val); - } - return unit_metadata; }; - - fn path_to_mdstring<'ll>(llcx: &'ll llvm::Context, path: &Path) -> &'ll llvm::Metadata { - let path_str = path_to_c_string(path); - unsafe { llvm::LLVMMDStringInContext2(llcx, path_str.as_ptr(), path_str.as_bytes().len()) } - } } /// Creates a `DW_TAG_member` entry inside the DIE represented by the given `type_di_node`. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 72e723aa849..b6c20cdcf0c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -55,7 +55,6 @@ const DW_TAG_arg_variable: c_uint = 0x101; /// A context object for maintaining all state needed by the debuginfo module. pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { - llcontext: &'ll llvm::Context, llmod: &'ll llvm::Module, builder: &'ll mut DIBuilder<'ll>, created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>, @@ -78,9 +77,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { debug!("CodegenUnitDebugContext::new"); let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; // DIBuilder inherits context from the module, so we'd better use the same one - let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; CodegenUnitDebugContext { - llcontext, llmod, builder, created_files: Default::default(), diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8fc586d2c8f..5fad7583e1a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2269,7 +2269,6 @@ unsafe extern "C" { PGOUsePath: *const c_char, InstrumentCoverage: bool, InstrProfileOutput: *const c_char, - InstrumentGCOV: bool, PGOSampleUsePath: *const c_char, DebugInfoForProfiling: bool, llvm_selfprofiler: *mut c_void, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 8445d16befb..d977cca247e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -90,7 +90,6 @@ pub struct ModuleConfig { pub pgo_sample_use: Option<PathBuf>, pub debug_info_for_profiling: bool, pub instrument_coverage: bool, - pub instrument_gcov: bool, pub sanitizer: SanitizerSet, pub sanitizer_recover: SanitizerSet, @@ -123,12 +122,7 @@ pub struct ModuleConfig { } impl ModuleConfig { - fn new( - kind: ModuleKind, - tcx: TyCtxt<'_>, - no_builtins: bool, - is_compiler_builtins: bool, - ) -> ModuleConfig { + fn new(kind: ModuleKind, tcx: TyCtxt<'_>, no_builtins: bool) -> ModuleConfig { // If it's a regular module, use `$regular`, otherwise use `$other`. // `$regular` and `$other` are evaluated lazily. macro_rules! if_regular { @@ -189,13 +183,6 @@ impl ModuleConfig { pgo_sample_use: if_regular!(sess.opts.unstable_opts.profile_sample_use.clone(), None), debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling, instrument_coverage: if_regular!(sess.instrument_coverage(), false), - instrument_gcov: if_regular!( - // compiler_builtins overrides the codegen-units settings, - // which is incompatible with -Zprofile which requires that - // only a single codegen unit is used per crate. - sess.opts.unstable_opts.profile && !is_compiler_builtins, - false - ), sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()), sanitizer_dataflow_abilist: if_regular!( @@ -473,16 +460,12 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>( let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); - let is_compiler_builtins = attr::contains_name(crate_attrs, sym::compiler_builtins); let crate_info = CrateInfo::new(tcx, target_cpu); - let regular_config = - ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins); - let metadata_config = - ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins); - let allocator_config = - ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins); + let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins); + let metadata_config = ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins); + let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins); let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); let (codegen_worker_send, codegen_worker_receive) = channel(); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index da779a16569..0b81f469371 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -43,7 +43,7 @@ fn associated_type_bounds<'tcx>( match filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); } @@ -122,7 +122,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( PredicateFilter::SelfOnly => { return None; } - PredicateFilter::SelfThatDefines(_) + PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst | PredicateFilter::SelfAndAssociatedTypeBounds | PredicateFilter::ConstIfConst => { @@ -329,7 +329,7 @@ fn opaque_type_bounds<'tcx>( match filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { // Associated types are implicitly sized unless a `?Sized` bound is found icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index efe84e0006f..7ce12d48160 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -557,7 +557,11 @@ pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name)) + implied_predicates_with_filter( + tcx, + trait_def_id, + PredicateFilter::SelfTraitThatDefines(assoc_name), + ) } pub(super) fn explicit_implied_predicates_of<'tcx>( @@ -586,7 +590,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let Some(trait_def_id) = trait_def_id.as_local() else { // if `assoc_name` is None, then the query should've been redirected to an // external provider - assert_matches!(filter, PredicateFilter::SelfThatDefines(_)); + assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_)); return tcx.explicit_super_predicates_of(trait_def_id); }; @@ -606,12 +610,8 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let mut bounds = Bounds::default(); icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); - let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics( - generics, - item.owner_id.def_id, - self_param_ty, - filter, - ); + let where_bounds_that_match = + icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter); // Combine the two lists to form the complete set of superbounds: let implied_bounds = @@ -652,7 +652,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( } // Make sure when elaborating supertraits, probing for associated types, etc., -// we really truly are elaborating clauses that have `Self` as their self type. +// we really truly are elaborating clauses that have `ty` as their self type. // This is very important since downstream code relies on this being correct. pub(super) fn assert_only_contains_predicates_from<'tcx>( filter: PredicateFilter, @@ -664,7 +664,7 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } match filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { + PredicateFilter::SelfOnly => { for (clause, _) in bounds { match clause.kind().skip_binder() { ty::ClauseKind::Trait(trait_predicate) => { @@ -704,6 +704,33 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } } } + PredicateFilter::SelfTraitThatDefines(_) => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::Trait(trait_predicate) => { + assert_eq!( + trait_predicate.self_ty(), + ty, + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + + ty::ClauseKind::Projection(_) + | ty::ClauseKind::TypeOutlives(_) + | ty::ClauseKind::RegionOutlives(_) + | ty::ClauseKind::ConstArgHasType(_, _) + | ty::ClauseKind::WellFormed(_) + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { + bug!( + "unexpected non-`Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } PredicateFilter::ConstIfConst => { for (clause, _) in bounds { match clause.kind().skip_binder() { @@ -767,21 +794,16 @@ pub(super) fn type_param_predicates<'tcx>( None => {} } - use rustc_hir::*; - use rustc_middle::ty::Ty; - // In the HIR, bounds can derive from two places. Either // written inline like `<T: Foo>` or in a where-clause like // `where T: Foo`. let param_id = tcx.local_def_id_to_hir_id(def_id); let param_owner = tcx.hir().ty_param_owner(def_id); - let generics = tcx.generics_of(param_owner); - let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - let ty = Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner { + // FIXME: Shouldn't this be unreachable? None } else { tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local()) @@ -801,8 +823,9 @@ pub(super) fn type_param_predicates<'tcx>( let Some(hir_generics) = hir_node.generics() else { return result; }; + if let Node::Item(item) = hir_node - && let ItemKind::Trait(..) = item.kind + && let hir::ItemKind::Trait(..) = item.kind // Implied `Self: Trait` and supertrait bounds. && param_id == item_hir_id { @@ -811,23 +834,34 @@ pub(super) fn type_param_predicates<'tcx>( } let icx = ItemCtxt::new(tcx, item_def_id); - let extra_predicates = extend.into_iter().chain( - icx.probe_ty_param_bounds_in_generics( - hir_generics, - def_id, - ty, - PredicateFilter::SelfThatDefines(assoc_name), - ) - .into_iter() - .filter(|(predicate, _)| match predicate.kind().skip_binder() { - ty::ClauseKind::Trait(data) => data.self_ty().is_param(index), - _ => false, - }), + let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics( + hir_generics, + def_id, + PredicateFilter::SelfTraitThatDefines(assoc_name), + )); + + let bounds = + &*tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)); + + // Double check that the bounds *only* contain `SelfTy: Trait` preds. + let self_ty = match tcx.def_kind(def_id) { + DefKind::TyParam => Ty::new_param( + tcx, + tcx.generics_of(item_def_id) + .param_def_id_to_index(tcx, def_id.to_def_id()) + .expect("expected generic param to be owned by item"), + tcx.item_name(def_id.to_def_id()), + ), + DefKind::Trait | DefKind::TraitAlias => tcx.types.self_param, + _ => unreachable!(), + }; + assert_only_contains_predicates_from( + PredicateFilter::SelfTraitThatDefines(assoc_name), + bounds, + self_ty, ); - ty::EarlyBinder::bind( - tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)), - ) + ty::EarlyBinder::bind(bounds) } impl<'tcx> ItemCtxt<'tcx> { @@ -841,7 +875,6 @@ impl<'tcx> ItemCtxt<'tcx> { &self, hir_generics: &'tcx hir::Generics<'tcx>, param_def_id: LocalDefId, - ty: Ty<'tcx>, filter: PredicateFilter, ) -> Vec<(ty::Clause<'tcx>, Span)> { let mut bounds = Bounds::default(); @@ -851,13 +884,21 @@ impl<'tcx> ItemCtxt<'tcx> { continue; }; - let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) { - ty - } else if matches!(filter, PredicateFilter::All) { - self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty) - } else { - continue; - }; + match filter { + _ if predicate.is_param_bound(param_def_id.to_def_id()) => { + // Ok + } + PredicateFilter::All => { + // Ok + } + PredicateFilter::SelfOnly + | PredicateFilter::SelfTraitThatDefines(_) + | PredicateFilter::SelfConstIfConst + | PredicateFilter::SelfAndAssociatedTypeBounds => continue, + PredicateFilter::ConstIfConst => unreachable!(), + } + + let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty); let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); self.lowerer().lower_bounds( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 8cc475b536d..85ba88333f9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -152,9 +152,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 'tcx: 'hir, { for hir_bound in hir_bounds { - // In order to avoid cycles, when we're lowering `SelfThatDefines`, + // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`, // we skip over any traits that don't define the given associated type. - if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter { + if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter { if let Some(trait_ref) = hir_bound.trait_ref() && let Some(trait_did) = trait_ref.trait_def_id() && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name) @@ -389,7 +389,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match predicate_filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { bounds.push_projection_bound( tcx, @@ -400,6 +399,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constraint.span, ); } + // SelfTraitThatDefines is only interested in trait predicates. + PredicateFilter::SelfTraitThatDefines(_) => {} // `ConstIfConst` is only interested in `~const` bounds. PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} } @@ -426,7 +427,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst => {} } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 848813ffcb8..fb23ad1b248 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -76,7 +76,7 @@ pub enum PredicateFilter { /// Only traits that reference `Self: ..` and define an associated type /// with the given ident are implied by the trait. This mode exists to /// side-step query cycles when lowering associated types. - SelfThatDefines(Ident), + SelfTraitThatDefines(Ident), /// Only traits that reference `Self: ..` and their associated type bounds. /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr` @@ -730,9 +730,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } match predicate_filter { + // This is only concerned with trait predicates. + PredicateFilter::SelfTraitThatDefines(..) => { + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + } PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(..) | PredicateFilter::SelfAndAssociatedTypeBounds => { debug!(?poly_trait_ref); bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index cceaabaff65..4f579b05d83 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -169,19 +169,34 @@ pub(crate) struct MissingParenthesesInRange { pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] - Call, + Call { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] - Method, + Method { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] - Path, + Path { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] - UnionField, + UnionField { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] - Deref, + Deref { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, } #[derive(LintDiagnostic)] @@ -191,6 +206,64 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { #[note] pub obligation_span: Span, pub obligation: ty::Predicate<'tcx>, + #[subdiagnostic] + pub sugg: SuggestAnnotations, +} + +#[derive(Clone)] +pub(crate) enum SuggestAnnotation { + Unit(Span), + Path(Span), + Local(Span), + Turbo(Span, usize, usize), +} + +#[derive(Clone)] +pub(crate) struct SuggestAnnotations { + pub suggestions: Vec<SuggestAnnotation>, +} +impl Subdiagnostic for SuggestAnnotations { + fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( + self, + diag: &mut Diag<'_, G>, + _: &F, + ) { + if self.suggestions.is_empty() { + return; + } + + let mut suggestions = vec![]; + for suggestion in self.suggestions { + match suggestion { + SuggestAnnotation::Unit(span) => { + suggestions.push((span, "()".to_string())); + } + SuggestAnnotation::Path(span) => { + suggestions.push((span.shrink_to_lo(), "<() as ".to_string())); + suggestions.push((span.shrink_to_hi(), ">".to_string())); + } + SuggestAnnotation::Local(span) => { + suggestions.push((span, ": ()".to_string())); + } + SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push(( + span, + format!( + "::<{}>", + (0..n_args) + .map(|i| if i == idx { "()" } else { "_" }) + .collect::<Vec<_>>() + .join(", "), + ), + )), + } + } + + diag.multipart_suggestion_verbose( + "use `()` annotations to avoid fallback changes", + suggestions, + Applicability::MachineApplicable, + ); + } } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 68776c52555..8d8573c65c5 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,11 +1,15 @@ use std::cell::OnceCell; +use std::ops::ControlFlow; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::iterate::DepthFirstSearch; use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::graph::{self}; use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; @@ -14,7 +18,7 @@ use rustc_span::{DUMMY_SP, Span}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::debug; -use crate::{FnCtxt, TypeckRootCtxt, errors}; +use crate::{FnCtxt, errors}; #[derive(Copy, Clone)] pub(crate) enum DivergingFallbackBehavior { @@ -321,7 +325,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len()); let unsafe_infer_vars = OnceCell::new(); - self.lint_obligations_broken_by_never_type_fallback_change(behavior, &diverging_vids); + self.lint_obligations_broken_by_never_type_fallback_change( + behavior, + &diverging_vids, + &coercion_graph, + ); for &diverging_vid in &diverging_vids { let diverging_ty = Ty::new_var(self.tcx, diverging_vid); @@ -419,7 +427,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { root_vid: ty::TyVid, ) { let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| { - let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id); + let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_id); debug!(?unsafe_infer_vars); unsafe_infer_vars }); @@ -429,19 +437,31 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .filter_map(|x| unsafe_infer_vars.get(&x).copied()) .collect::<Vec<_>>(); + let sugg = self.try_to_suggest_annotations(&[root_vid], coercion_graph); + for (hir_id, span, reason) in affected_unsafe_infer_vars { self.tcx.emit_node_span_lint( lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, hir_id, span, match reason { - UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call, - UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method, - UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path, + UnsafeUseReason::Call => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Call { sugg: sugg.clone() } + } + UnsafeUseReason::Method => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Method { sugg: sugg.clone() } + } + UnsafeUseReason::Path => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Path { sugg: sugg.clone() } + } UnsafeUseReason::UnionField => { - errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField + errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField { + sugg: sugg.clone(), + } + } + UnsafeUseReason::Deref => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { sugg: sugg.clone() } } - UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref, }, ); } @@ -451,6 +471,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { &self, behavior: DivergingFallbackBehavior, diverging_vids: &[ty::TyVid], + coercions: &VecGraph<ty::TyVid, true>, ) { let DivergingFallbackBehavior::ToUnit = behavior else { return }; @@ -478,13 +499,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> { }; // If we have no errors with `fallback = ()`, but *do* have errors with `fallback = !`, - // then this code will be broken by the never type fallback change.qba + // then this code will be broken by the never type fallback change. let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit); if unit_errors.is_empty() && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never) && let [ref mut never_error, ..] = never_errors.as_mut_slice() { self.adjust_fulfillment_error_for_expr_obligation(never_error); + let sugg = self.try_to_suggest_annotations(diverging_vids, coercions); self.tcx.emit_node_span_lint( lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, self.tcx.local_def_id_to_hir_id(self.body_id), @@ -492,6 +514,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { errors::DependencyOnUnitNeverTypeFallback { obligation_span: never_error.obligation.cause.span, obligation: never_error.obligation.predicate, + sugg, }, ) } @@ -541,6 +564,153 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> { Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) } + + /// Given a set of diverging vids and coercions, walk the HIR to gather a + /// set of suggestions which can be applied to preserve fallback to unit. + fn try_to_suggest_annotations( + &self, + diverging_vids: &[ty::TyVid], + coercions: &VecGraph<ty::TyVid, true>, + ) -> errors::SuggestAnnotations { + let body = + self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner"); + // For each diverging var, look through the HIR for a place to give it + // a type annotation. We do this per var because we only really need one + // suggestion to influence a var to be `()`. + let suggestions = diverging_vids + .iter() + .copied() + .filter_map(|vid| { + let reachable_vids = + graph::depth_first_search_as_undirected(coercions, vid).collect(); + AnnotateUnitFallbackVisitor { reachable_vids, fcx: self } + .visit_expr(body.value) + .break_value() + }) + .collect(); + errors::SuggestAnnotations { suggestions } + } +} + +/// Try to walk the HIR to find a place to insert a useful suggestion +/// to preserve fallback to `()` in 2024. +struct AnnotateUnitFallbackVisitor<'a, 'tcx> { + reachable_vids: FxHashSet<ty::TyVid>, + fcx: &'a FnCtxt<'a, 'tcx>, +} +impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> { + // For a given path segment, if it's missing a turbofish, try to suggest adding + // one so we can constrain an argument to `()`. To keep the suggestion simple, + // we want to simply suggest `_` for all the other args. This (for now) only + // works when there are only type variables (and region variables, since we can + // elide them)... + fn suggest_for_segment( + &self, + arg_segment: &'tcx hir::PathSegment<'tcx>, + def_id: DefId, + id: HirId, + ) -> ControlFlow<errors::SuggestAnnotation> { + if arg_segment.args.is_none() + && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id) + && let generics = self.fcx.tcx.generics_of(def_id) + && let args = &all_args[generics.parent_count..] + // We can't turbofish consts :( + && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_))) + { + let n_tys = args + .iter() + .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_))) + .count(); + for (idx, arg) in args.iter().enumerate() { + if let Some(ty) = arg.as_type() + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Turbo( + arg_segment.ident.span.shrink_to_hi(), + n_tys, + idx, + )); + } + } + } + ControlFlow::Continue(()) + } +} +impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { + type Result = ControlFlow<errors::SuggestAnnotation>; + + fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { + // Try to replace `_` with `()`. + if let hir::TyKind::Infer = hir_ty.kind + && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Unit(hir_ty.span)); + } + hir::intravisit::walk_ty(self, hir_ty) + } + + fn visit_qpath( + &mut self, + qpath: &'tcx rustc_hir::QPath<'tcx>, + id: HirId, + _span: Span, + ) -> Self::Result { + let arg_segment = match qpath { + hir::QPath::Resolved(_, path) => { + path.segments.last().expect("paths should have a segment") + } + hir::QPath::TypeRelative(_, segment) => segment, + hir::QPath::LangItem(..) => { + return hir::intravisit::walk_qpath(self, qpath, id); + } + }; + // Alternatively, try to turbofish `::<_, (), _>`. + if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() { + self.suggest_for_segment(arg_segment, def_id, id)?; + } + hir::intravisit::walk_qpath(self, qpath, id) + } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + // Try to suggest adding an explicit qself `()` to a trait method path. + // i.e. changing `Default::default()` to `<() as Default>::default()`. + if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind + && let Res::Def(DefKind::AssocFn, def_id) = path.res + && self.fcx.tcx.trait_of_item(def_id).is_some() + && let self_ty = self.fcx.typeck_results.borrow().node_args(expr.hir_id).type_at(0) + && let Some(vid) = self.fcx.root_vid(self_ty) + && self.reachable_vids.contains(&vid) + && let [.., trait_segment, _method_segment] = path.segments + { + let span = path.span.shrink_to_lo().to(trait_segment.ident.span); + return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); + } + // Or else, try suggesting turbofishing the method args. + if let hir::ExprKind::MethodCall(segment, ..) = expr.kind + && let Some(def_id) = + self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id) + { + self.suggest_for_segment(segment, def_id, expr.hir_id)?; + } + hir::intravisit::walk_expr(self, expr) + } + + fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result { + // For a local, try suggest annotating the type if it's missing. + if let None = local.ty + && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Local( + local.pat.span.shrink_to_hi(), + )); + } + hir::intravisit::walk_local(self, local) + } } #[derive(Debug, Copy, Clone)] @@ -569,27 +739,26 @@ pub(crate) enum UnsafeUseReason { /// /// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }` fn compute_unsafe_infer_vars<'a, 'tcx>( - root_ctxt: &'a TypeckRootCtxt<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, body_id: LocalDefId, ) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> { - let body = - root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx> { - root_ctxt: &'a TypeckRootCtxt<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, res: &'a mut UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)>, } impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_> { fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) { - let typeck_results = self.root_ctxt.typeck_results.borrow(); + let typeck_results = self.fcx.typeck_results.borrow(); match ex.kind { hir::ExprKind::MethodCall(..) => { if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) - && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity() - && let sig = method_ty.fn_sig(self.root_ctxt.tcx) + && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity() + && let sig = method_ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -609,7 +778,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( let func_ty = typeck_results.expr_ty(func); if func_ty.is_fn() - && let sig = func_ty.fn_sig(self.root_ctxt.tcx) + && let sig = func_ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -640,7 +809,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( // If this path refers to an unsafe function, collect inference variables which may affect it. // `is_fn` excludes closures, but those can't be unsafe. if ty.is_fn() - && let sig = ty.fn_sig(self.root_ctxt.tcx) + && let sig = ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -698,7 +867,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( } } - UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value); + UnsafeInferVarsVisitor { fcx, res: &mut res }.visit_expr(&body.value); debug!(?res, "collected the following unsafe vars for {body_id:?}"); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d3762e739db..35bba149d0a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -832,8 +832,6 @@ fn test_unstable_options_tracking_hash() { tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); tracked!(print_fuel, Some("abc".to_string())); - tracked!(profile, true); - tracked!(profile_emit, Some(PathBuf::from("abc"))); tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(regparm, Some(3)); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 88878a018e7..48dd8e38a03 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -204,7 +204,10 @@ fn lint_nan<'tcx>( return false; }; - matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::f32_nan | sym::f64_nan)) + matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::f16_nan | sym::f32_nan | sym::f64_nan | sym::f128_nan) + ) } _ => false, } diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3e906f89c15..3b7dc6de825 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -42,7 +42,6 @@ #if LLVM_VERSION_GE(19, 0) #include "llvm/Support/PGOOptions.h" #endif -#include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" @@ -714,9 +713,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, - const char *InstrProfileOutput, bool InstrumentGCOV, - const char *PGOSampleUsePath, bool DebugInfoForProfiling, - void *LlvmSelfProfiler, + const char *InstrProfileOutput, const char *PGOSampleUsePath, + bool DebugInfoForProfiling, void *LlvmSelfProfiler, LLVMRustSelfProfileBeforePassCallback BeforePassCallback, LLVMRustSelfProfileAfterPassCallback AfterPassCallback, const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins, @@ -847,13 +845,6 @@ extern "C" LLVMRustResult LLVMRustOptimize( }); } - if (InstrumentGCOV) { - PipelineStartEPCallbacks.push_back( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault())); - }); - } - if (InstrumentCoverage) { PipelineStartEPCallbacks.push_back( [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) { diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 3b0151b1f94..cece700b4dd 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -27,7 +27,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } -snap = "1" tempfile = "3.2" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 16623915c40..d2be6ae8d69 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -778,9 +778,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { if self.sess.opts.unstable_opts.no_profiler_runtime - || !(self.sess.instrument_coverage() - || self.sess.opts.unstable_opts.profile - || self.sess.opts.cg.profile_generate.enabled()) + || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled()) { return; } diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index a4a69ae9514..f924ed48b6f 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -213,7 +213,7 @@ //! metadata::locator or metadata::creader for all the juicy details! use std::borrow::Cow; -use std::io::{Read, Result as IoResult, Write}; +use std::io::{Result as IoResult, Write}; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::{cmp, fmt}; @@ -232,7 +232,6 @@ use rustc_session::utils::CanonicalizedPath; use rustc_span::Span; use rustc_span::symbol::Symbol; use rustc_target::spec::{Target, TargetTriple}; -use snap::read::FrameDecoder; use tracing::{debug, info}; use crate::creader::{Library, MetadataLoader}; @@ -792,7 +791,6 @@ fn get_metadata_section<'p>( CrateFlavor::Dylib => { let buf = loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?; - // The header is uncompressed let header_len = METADATA_HEADER.len(); // header + u64 length of data let data_start = header_len + 8; @@ -806,7 +804,7 @@ fn get_metadata_section<'p>( ))); } - // Length of the compressed stream - this allows linkers to pad the section if they want + // Length of the metadata - this allows linkers to pad the section if they want let Ok(len_bytes) = <[u8; 8]>::try_from(&buf[header_len..cmp::min(data_start, buf.len())]) else { @@ -814,29 +812,10 @@ fn get_metadata_section<'p>( "invalid metadata length found".to_string(), )); }; - let compressed_len = u64::from_le_bytes(len_bytes) as usize; + let metadata_len = u64::from_le_bytes(len_bytes) as usize; // Header is okay -> inflate the actual metadata - let compressed_bytes = buf.slice(|buf| &buf[data_start..(data_start + compressed_len)]); - if &compressed_bytes[..cmp::min(METADATA_HEADER.len(), compressed_bytes.len())] - == METADATA_HEADER - { - // The metadata was not actually compressed. - compressed_bytes - } else { - debug!("inflating {} bytes of compressed metadata", compressed_bytes.len()); - // Assume the decompressed data will be at least the size of the compressed data, so we - // don't have to grow the buffer as much. - let mut inflated = Vec::with_capacity(compressed_bytes.len()); - FrameDecoder::new(&*compressed_bytes).read_to_end(&mut inflated).map_err(|_| { - MetadataError::LoadFailure(format!( - "failed to decompress metadata: {}", - filename.display() - )) - })?; - - slice_owned(inflated, Deref::deref) - } + buf.slice(|buf| &buf[data_start..(data_start + metadata_len)]) } CrateFlavor::Rmeta => { // mmap the file, because only a small fraction of it is read. diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index d733e32f209..5ee3b4015eb 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2453,7 +2453,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let output_types = parse_output_types(early_dcx, &unstable_opts, matches); let mut cg = CodegenOptions::build(early_dcx, matches); - let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( + let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto( early_dcx, &output_types, matches, @@ -2476,18 +2476,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); - if unstable_opts.profile && incremental.is_some() { - early_dcx.early_fatal("can't instrument with gcov profiling when compiling incrementally"); - } - if unstable_opts.profile { - match codegen_units { - Some(1) => {} - None => codegen_units = Some(1), - Some(_) => early_dcx - .early_fatal("can't instrument with gcov profiling with multiple codegen units"), - } - } - if cg.profile_generate.enabled() && cg.profile_use.is_some() { early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive"); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 54a4621db24..2b158627751 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1985,13 +1985,8 @@ options! { proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, parse_proc_macro_execution_strategy, [UNTRACKED], "how to run proc-macro code (default: same-thread)"), - profile: bool = (false, parse_bool, [TRACKED], - "insert profiling code (default: no)"), profile_closures: bool = (false, parse_no_flag, [UNTRACKED], "profile size of closures"), - profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], - "file path to emit profiling data at runtime when using 'profile' \ - (default based on relative source path)"), profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED], diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 74b198c4fdd..4cf52042a57 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1254,11 +1254,9 @@ impl<T> SizedTypeProperties for T {} /// /// Nested field accesses may be used, but not array indexes. /// -/// Enum variants may be traversed as if they were fields. Variants themselves do -/// not have an offset. -/// -/// However, on stable only a single field name is supported, which blocks the use of -/// enum support. +/// If the nightly-only feature `offset_of_enum` is enabled, +/// variants may be traversed as if they were fields. +/// Variants themselves do not have an offset. /// /// Visibility is respected - all types and fields must be visible to the call site: /// diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 99ddf58104c..4ab4e60773f 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1056,6 +1056,14 @@ pub fn rustc_cargo( cargo.rustflag("-l").rustflag("Enzyme-19"); } + // Building with protected visibility reduces the number of dynamic relocations needed, giving + // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object + // with direct references to protected symbols, so for now we only use protected symbols if + // linking with LLD is enabled. + if builder.build.config.lld_mode.is_used() { + cargo.rustflag("-Zdefault-visibility=protected"); + } + // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary // and may just be a time sink. if compiler.stage != 0 { diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 51964977933..704fa46ab1e 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -571,6 +571,7 @@ Select which editor you would like to set up [default: None]: "; "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", ], EditorKind::Emacs => vec![ "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index ed091d8fc57..41da47e9206 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -2,12 +2,8 @@ ## Introduction -The Rust compiler includes two code coverage implementations: - -- A GCC-compatible, gcov-based coverage implementation, enabled with `-Z profile`, which derives coverage data based on DebugInfo. -- A source-based code coverage implementation, enabled with `-C instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data. - -This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-C instrument-coverage` compiler flag. +This document describes how to enable and use LLVM instrumentation-based coverage, +via the `-C instrument-coverage` compiler flag. ## How it works diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index 74e873e35ff..d9dba641495 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -40,8 +40,9 @@ include: of a delimited expression, delimited expressions are generally combinable, regardless of the number of members. Previously only applied with exactly one member (except for closures with explicit blocks). -- When line-breaking a binary operator, if the first operand spans multiple - lines, use the base indentation of the last line. +- When line-breaking an assignment operator, if the left-hand side spans + multiple lines, use the base indentation of the last line of the left-hand + side to indent the right-hand side. - Miscellaneous `rustfmt` bugfixes. - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 3bb0ee6d5ff..4f63a632030 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -328,9 +328,9 @@ foo_bar Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather than at other binary operators. -If line-breaking at a binary operator (including assignment operators) where the -first operand spans multiple lines, use the base indentation of the *last* -line of the first operand, and indent relative to that: +If line-breaking an assignment operator where the left-hand side spans multiple +lines, use the base indentation of the *last* line of the left-hand side, and +indent the right-hand side relative to that: ```rust impl SomeType { @@ -344,12 +344,6 @@ impl SomeType { self.array[array_index as usize] .as_mut() .expect("thing must exist") - .extra_info - + long_long_long_long_long_long_long_long_long_long_long_long_long_long_long; - - self.array[array_index as usize] - .as_mut() - .expect("thing must exist") .extra_info = Some(ExtraInfo { parent, count: count as u16, diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md deleted file mode 100644 index 71303bfaff2..00000000000 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ /dev/null @@ -1,27 +0,0 @@ -# `profile` - -The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). - ------------------------- - -This feature allows the generation of code coverage reports. - -Set the `-Zprofile` compiler flag in order to enable gcov profiling. - -For example: -```Bash -cargo new testgcov --bin -cd testgcov -export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" -export CARGO_INCREMENTAL=0 -cargo build -cargo run -``` - -Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created. -You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/mozilla/grcov). - -Please note that `RUSTFLAGS` by default applies to everything that cargo builds and runs during a build! -When the `--target` flag is explicitly passed to cargo, the `RUSTFLAGS` no longer apply to build scripts and procedural macros. -For more fine-grained control consider passing a `RUSTC_WRAPPER` program to cargo that only adds the profiling flags to -rustc for the specific crates you want to profile. diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index a20105f0ef3..d1b186fd316 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -1,6 +1,5 @@ { "git.detectSubmodulesLimit": 20, - "rust-analyzer.check.invocationLocation": "root", "rust-analyzer.check.invocationStrategy": "once", "rust-analyzer.check.overrideCommand": [ "python3", @@ -24,7 +23,6 @@ "rust-analyzer.procMacro.server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv", "rust-analyzer.procMacro.enable": true, "rust-analyzer.cargo.buildScripts.enable": true, - "rust-analyzer.cargo.buildScripts.invocationLocation": "root", "rust-analyzer.cargo.buildScripts.invocationStrategy": "once", "rust-analyzer.cargo.buildScripts.overrideCommand": [ "python3", diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c62144be3da..d49b4320db6 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -5,6 +5,7 @@ use std::sync::{Arc, OnceLock as OnceCell}; use std::{fmt, iter}; use arrayvec::ArrayVec; +use rustc_abi::{ExternAbi, VariantIdx}; use rustc_ast::MetaItemInner; use rustc_ast_pretty::pprust; use rustc_attr::{ConstStability, Deprecation, Stability, StableSince}; @@ -26,8 +27,6 @@ use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, FileName, Loc}; -use rustc_target::abi::VariantIdx; -use rustc_target::spec::abi::Abi; use thin_vec::ThinVec; use tracing::{debug, trace}; use {rustc_ast as ast, rustc_hir as hir}; @@ -656,7 +655,7 @@ impl Item { let def_id = self.def_id().unwrap(); let abi = tcx.fn_sig(def_id).skip_binder().abi(); hir::FnHeader { - safety: if abi == Abi::RustIntrinsic { + safety: if abi == ExternAbi::RustIntrinsic { intrinsic_operation_unsafety(tcx, def_id.expect_local()) } else { safety @@ -2342,7 +2341,7 @@ pub(crate) struct BareFunctionDecl { pub(crate) safety: hir::Safety, pub(crate) generic_params: Vec<GenericParamDef>, pub(crate) decl: FnDecl, - pub(crate) abi: Abi, + pub(crate) abi: ExternAbi, } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 47c21d89177..e9d5ba2ea57 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -13,6 +13,7 @@ use std::fmt::{self, Display, Write}; use std::iter::{self, once}; use itertools::Itertools; +use rustc_abi::ExternAbi; use rustc_attr::{ConstStability, StabilityLevel, StableSince}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -23,7 +24,6 @@ use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_span::symbol::kw; use rustc_span::{Symbol, sym}; -use rustc_target::spec::abi::Abi; use tracing::{debug, trace}; use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length}; @@ -1787,11 +1787,11 @@ impl clean::AssocItemConstraint { } } -pub(crate) fn print_abi_with_space(abi: Abi) -> impl Display { +pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display { display_fn(move |f| { let quot = if f.alternate() { "\"" } else { """ }; match abi { - Abi::Rust => Ok(()), + ExternAbi::Rust => Ok(()), abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()), } }) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 5e9cbef99a9..c6a2d87cbd0 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use itertools::Itertools; use rinja::Template; +use rustc_abi::VariantIdx; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_hir as hir; @@ -14,7 +15,6 @@ use rustc_index::IndexVec; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, kw, sym}; -use rustc_target::abi::VariantIdx; use tracing::{debug, info}; use super::type_layout::document_type_layout; diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 79209cee94f..d85ba3a2b14 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -1,13 +1,13 @@ use std::fmt; use rinja::Template; +use rustc_abi::{Primitive, TagEncoding, Variants}; use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self}; use rustc_span::symbol::Symbol; -use rustc_target::abi::{Primitive, TagEncoding, Variants}; use crate::html::format::display_fn; use crate::html::render::Context; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7270f170780..1c8303d4c20 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -4,6 +4,7 @@ #![allow(rustc::default_hash_types)] +use rustc_abi::ExternAbi; use rustc_ast::ast; use rustc_attr::DeprecatedSince; use rustc_hir::def::{CtorKind, DefKind}; @@ -11,7 +12,6 @@ use rustc_hir::def_id::DefId; use rustc_metadata::rendered_const; use rustc_middle::{bug, ty}; use rustc_span::{Pos, Symbol, sym}; -use rustc_target::spec::abi::Abi as RustcAbi; use rustdoc_json_types::*; use super::FullItemId; @@ -421,17 +421,17 @@ pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> FunctionHeader { } } -fn convert_abi(a: RustcAbi) -> Abi { +fn convert_abi(a: ExternAbi) -> Abi { match a { - RustcAbi::Rust => Abi::Rust, - RustcAbi::C { unwind } => Abi::C { unwind }, - RustcAbi::Cdecl { unwind } => Abi::Cdecl { unwind }, - RustcAbi::Stdcall { unwind } => Abi::Stdcall { unwind }, - RustcAbi::Fastcall { unwind } => Abi::Fastcall { unwind }, - RustcAbi::Aapcs { unwind } => Abi::Aapcs { unwind }, - RustcAbi::Win64 { unwind } => Abi::Win64 { unwind }, - RustcAbi::SysV64 { unwind } => Abi::SysV64 { unwind }, - RustcAbi::System { unwind } => Abi::System { unwind }, + ExternAbi::Rust => Abi::Rust, + ExternAbi::C { unwind } => Abi::C { unwind }, + ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind }, + ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind }, + ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind }, + ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind }, + ExternAbi::Win64 { unwind } => Abi::Win64 { unwind }, + ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind }, + ExternAbi::System { unwind } => Abi::System { unwind }, _ => Abi::Other(a.to_string()), } } diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 695c37f6d7b..424357e8473 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1364,7 +1364,6 @@ dependencies = [ "proc-macro-api", "proc-macro-test", "ra-ap-rustc_lexer", - "snap", "span", "stdx", "syntax-bridge", @@ -1889,12 +1888,6 @@ dependencies = [ ] [[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - -[[package]] name = "span" version = "0.0.0" dependencies = [ diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 3aa93b7b7b4..1099d2cb918 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -145,7 +145,6 @@ smallvec = { version = "1.10.0", features = [ "const_generics", ] } smol_str = "0.3.2" -snap = "1.1.0" text-size = "1.1.1" tracing = "0.1.40" tracing-tree = "0.3.0" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index e8d9677c928..4fabcc90067 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -16,7 +16,6 @@ doctest = false object.workspace = true libloading.workspace = true memmap2.workspace = true -snap.workspace = true stdx.workspace = true tt.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs index 1f7ef7914ba..7f0e95c50de 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs @@ -8,7 +8,6 @@ use std::{ use memmap2::Mmap; use object::read::{File as BinaryFile, Object, ObjectSection}; use paths::AbsPath; -use snap::read::FrameDecoder as SnapDecoder; #[derive(Debug)] #[allow(dead_code)] @@ -123,9 +122,8 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { let version = u32::from_be_bytes([dot_rustc[4], dot_rustc[5], dot_rustc[6], dot_rustc[7]]); // Last supported version is: // https://github.com/rust-lang/rust/commit/b94cfefc860715fb2adf72a6955423d384c69318 - let (snappy_portion, bytes_before_version) = match version { - 5 | 6 => (&dot_rustc[8..], 13), - 7 | 8 => { + let (mut metadata_portion, bytes_before_version) = match version { + 8 => { let len_bytes = &dot_rustc[8..12]; let data_len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize; (&dot_rustc[12..data_len + 12], 13) @@ -143,13 +141,6 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { } }; - let mut uncompressed: Box<dyn Read> = if &snappy_portion[0..4] == b"rust" { - // Not compressed. - Box::new(snappy_portion) - } else { - Box::new(SnapDecoder::new(snappy_portion)) - }; - // We're going to skip over the bytes before the version string, so basically: // 8 bytes for [b'r',b'u',b's',b't',0,0,0,5] // 4 or 8 bytes for [crate root bytes] @@ -157,11 +148,11 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { // so 13 or 17 bytes in total, and we should check the last of those bytes // to know the length let mut bytes = [0u8; 17]; - uncompressed.read_exact(&mut bytes[..bytes_before_version])?; + metadata_portion.read_exact(&mut bytes[..bytes_before_version])?; let length = bytes[bytes_before_version - 1]; let mut version_string_utf8 = vec![0u8; length as usize]; - uncompressed.read_exact(&mut version_string_utf8)?; + metadata_portion.read_exact(&mut version_string_utf8)?; let version_string = String::from_utf8(version_string_utf8); version_string.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 630838d46a2..f3bd72fe647 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -101,7 +101,6 @@ const EXCEPTIONS: ExceptionList = &[ ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), // rustc (license is the same as LLVM uses) ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 // cargo/... (because of serde) ("self_cell", "Apache-2.0"), // rustc (fluent translations) - ("snap", "BSD-3-Clause"), // rustc ("wasi-preview1-component-adapter-provider", "Apache-2.0 WITH LLVM-exception"), // rustc // tidy-alphabetical-end ]; @@ -163,7 +162,6 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[ ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 ("scip", "Apache-2.0"), - ("snap", "BSD-3-Clause"), // tidy-alphabetical-end ]; @@ -391,7 +389,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "sharded-slab", "shlex", "smallvec", - "snap", "stable_deref_trait", "stacker", "static_assertions", diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs deleted file mode 100644 index 58a1b53c040..00000000000 --- a/tests/run-make/profile/rmake.rs +++ /dev/null @@ -1,21 +0,0 @@ -// This test revolves around the rustc flag -Z profile, which should -// generate a .gcno file (initial profiling information) as well -// as a .gcda file (branch counters). The path where these are emitted -// should also be configurable with -Z profile-emit. This test checks -// that the files are produced, and then that the latter flag is respected. -// See https://github.com/rust-lang/rust/pull/42433 - -//@ ignore-cross-compile -//@ needs-profiler-runtime - -use run_make_support::{path, run, rustc}; - -fn main() { - rustc().arg("-g").arg("-Zprofile").input("test.rs").run(); - run("test"); - assert!(path("test.gcno").exists(), "no .gcno file"); - assert!(path("test.gcda").exists(), "no .gcda file"); - rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run(); - run("test"); - assert!(path("abc/abc.gcda").exists(), "gcda file not emitted to defined path"); -} diff --git a/tests/run-make/profile/test.rs b/tests/run-make/profile/test.rs deleted file mode 100644 index f328e4d9d04..00000000000 --- a/tests/run-make/profile/test.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 134fd098b7e..79eee2a3def 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let x: () = match true { + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/never-type-fallback-breaking.rs:27:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail | LL | deserialize()?; | ^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | deserialize::<()>()?; + | ++++++ warning: 2 warnings emitted diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed index 46b2d4e9c3f..2d88c274080 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed @@ -1,7 +1,15 @@ //@ check-pass //@ run-rustfix +#![feature(f16, f128)] + fn main() { + let x = 5f16; + let _ = x.is_nan(); + //~^ WARN incorrect NaN comparison + let _ = !x.is_nan(); + //~^ WARN incorrect NaN comparison + let x = 5f32; let _ = x.is_nan(); //~^ WARN incorrect NaN comparison @@ -14,6 +22,12 @@ fn main() { let _ = !x.is_nan(); //~^ WARN incorrect NaN comparison + let x = 5f128; + let _ = x.is_nan(); + //~^ WARN incorrect NaN comparison + let _ = !x.is_nan(); + //~^ WARN incorrect NaN comparison + let b = &2.3f32; if !b.is_nan() {} //~^ WARN incorrect NaN comparison diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.rs b/tests/ui/lint/invalid-nan-comparison-suggestion.rs index 558b433d794..91753447869 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.rs +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.rs @@ -1,7 +1,15 @@ //@ check-pass //@ run-rustfix +#![feature(f16, f128)] + fn main() { + let x = 5f16; + let _ = x == f16::NAN; + //~^ WARN incorrect NaN comparison + let _ = x != f16::NAN; + //~^ WARN incorrect NaN comparison + let x = 5f32; let _ = x == f32::NAN; //~^ WARN incorrect NaN comparison @@ -14,6 +22,12 @@ fn main() { let _ = x != f64::NAN; //~^ WARN incorrect NaN comparison + let x = 5f128; + let _ = x == f128::NAN; + //~^ WARN incorrect NaN comparison + let _ = x != f128::NAN; + //~^ WARN incorrect NaN comparison + let b = &2.3f32; if b != &f32::NAN {} //~^ WARN incorrect NaN comparison diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr index c310341de07..9d07d3f9240 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr @@ -1,18 +1,42 @@ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:6:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:8:13 | -LL | let _ = x == f32::NAN; +LL | let _ = x == f16::NAN; | ^^^^^^^^^^^^^ | = note: `#[warn(invalid_nan_comparisons)]` on by default help: use `f32::is_nan()` or `f64::is_nan()` instead | +LL - let _ = x == f16::NAN; +LL + let _ = x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:10:13 + | +LL | let _ = x != f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x != f16::NAN; +LL + let _ = !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:14:13 + | +LL | let _ = x == f32::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | LL - let _ = x == f32::NAN; LL + let _ = x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:8:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:16:13 | LL | let _ = x != f32::NAN; | ^^^^^^^^^^^^^ @@ -24,7 +48,7 @@ LL + let _ = !x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:12:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:20:13 | LL | let _ = x == f64::NAN; | ^^^^^^^^^^^^^ @@ -36,7 +60,7 @@ LL + let _ = x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:14:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:22:13 | LL | let _ = x != f64::NAN; | ^^^^^^^^^^^^^ @@ -48,7 +72,31 @@ LL + let _ = !x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:18:8 + --> $DIR/invalid-nan-comparison-suggestion.rs:26:13 + | +LL | let _ = x == f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x == f128::NAN; +LL + let _ = x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:28:13 + | +LL | let _ = x != f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x != f128::NAN; +LL + let _ = !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:32:8 | LL | if b != &f32::NAN {} | ^^^^^^^^^^^^^^ @@ -60,7 +108,7 @@ LL + if !b.is_nan() {} | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:22:8 + --> $DIR/invalid-nan-comparison-suggestion.rs:36:8 | LL | if b != { &f32::NAN } {} | ^^^^^^^^^^^^^^^^^^ @@ -72,7 +120,7 @@ LL + if !b.is_nan() {} | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:26:9 + --> $DIR/invalid-nan-comparison-suggestion.rs:40:9 | LL | / b != { LL | | @@ -87,7 +135,7 @@ LL + !b.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:35:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:49:13 | LL | let _ = nan!() == number!(); | ^^^^^^^^^^^^^^^^^^^ @@ -99,7 +147,7 @@ LL + let _ = number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:37:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:51:13 | LL | let _ = number!() != nan!(); | ^^^^^^^^^^^^^^^^^^^ @@ -110,5 +158,5 @@ LL - let _ = number!() != nan!(); LL + let _ = !number!().is_nan(); | -warning: 9 warnings emitted +warning: 13 warnings emitted diff --git a/tests/ui/lint/invalid-nan-comparison.rs b/tests/ui/lint/invalid-nan-comparison.rs index 202a5e27e8e..1a2c8a7c5a0 100644 --- a/tests/ui/lint/invalid-nan-comparison.rs +++ b/tests/ui/lint/invalid-nan-comparison.rs @@ -1,13 +1,38 @@ //@ check-pass +#![feature(f16, f128)] + fn main() { + f16(); f32(); f64(); + f128(); } const TEST: bool = 5f32 == f32::NAN; //~^ WARN incorrect NaN comparison +fn f16() { + macro_rules! number { () => { 5f16 }; } + let x = number!(); + x == f16::NAN; + //~^ WARN incorrect NaN comparison + x != f16::NAN; + //~^ WARN incorrect NaN comparison + x < f16::NAN; + //~^ WARN incorrect NaN comparison + x > f16::NAN; + //~^ WARN incorrect NaN comparison + x <= f16::NAN; + //~^ WARN incorrect NaN comparison + x >= f16::NAN; + //~^ WARN incorrect NaN comparison + number!() == f16::NAN; + //~^ WARN incorrect NaN comparison + f16::NAN != number!(); + //~^ WARN incorrect NaN comparison +} + fn f32() { macro_rules! number { () => { 5f32 }; } let x = number!(); @@ -49,3 +74,24 @@ fn f64() { f64::NAN != number!(); //~^ WARN incorrect NaN comparison } + +fn f128() { + macro_rules! number { () => { 5f128 }; } + let x = number!(); + x == f128::NAN; + //~^ WARN incorrect NaN comparison + x != f128::NAN; + //~^ WARN incorrect NaN comparison + x < f128::NAN; + //~^ WARN incorrect NaN comparison + x > f128::NAN; + //~^ WARN incorrect NaN comparison + x <= f128::NAN; + //~^ WARN incorrect NaN comparison + x >= f128::NAN; + //~^ WARN incorrect NaN comparison + number!() == f128::NAN; + //~^ WARN incorrect NaN comparison + f128::NAN != number!(); + //~^ WARN incorrect NaN comparison +} diff --git a/tests/ui/lint/invalid-nan-comparison.stderr b/tests/ui/lint/invalid-nan-comparison.stderr index 054c06d38b3..486d2a9636c 100644 --- a/tests/ui/lint/invalid-nan-comparison.stderr +++ b/tests/ui/lint/invalid-nan-comparison.stderr @@ -1,5 +1,5 @@ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:8:20 + --> $DIR/invalid-nan-comparison.rs:12:20 | LL | const TEST: bool = 5f32 == f32::NAN; | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,79 @@ LL + const TEST: bool = 5f32.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:14:5 + --> $DIR/invalid-nan-comparison.rs:18:5 + | +LL | x == f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x == f16::NAN; +LL + x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:20:5 + | +LL | x != f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x != f16::NAN; +LL + !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:22:5 + | +LL | x < f16::NAN; + | ^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:24:5 + | +LL | x > f16::NAN; + | ^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:26:5 + | +LL | x <= f16::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:28:5 + | +LL | x >= f16::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:30:5 + | +LL | number!() == f16::NAN; + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - number!() == f16::NAN; +LL + number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:32:5 + | +LL | f16::NAN != number!(); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - f16::NAN != number!(); +LL + !number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:39:5 | LL | x == f32::NAN; | ^^^^^^^^^^^^^ @@ -24,7 +96,7 @@ LL + x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:16:5 + --> $DIR/invalid-nan-comparison.rs:41:5 | LL | x != f32::NAN; | ^^^^^^^^^^^^^ @@ -36,31 +108,31 @@ LL + !x.is_nan(); | warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:18:5 + --> $DIR/invalid-nan-comparison.rs:43:5 | LL | x < f32::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:20:5 + --> $DIR/invalid-nan-comparison.rs:45:5 | LL | x > f32::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:22:5 + --> $DIR/invalid-nan-comparison.rs:47:5 | LL | x <= f32::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:24:5 + --> $DIR/invalid-nan-comparison.rs:49:5 | LL | x >= f32::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:26:5 + --> $DIR/invalid-nan-comparison.rs:51:5 | LL | number!() == f32::NAN; | ^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +144,7 @@ LL + number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:28:5 + --> $DIR/invalid-nan-comparison.rs:53:5 | LL | f32::NAN != number!(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +156,7 @@ LL + !number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:35:5 + --> $DIR/invalid-nan-comparison.rs:60:5 | LL | x == f64::NAN; | ^^^^^^^^^^^^^ @@ -96,7 +168,7 @@ LL + x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:37:5 + --> $DIR/invalid-nan-comparison.rs:62:5 | LL | x != f64::NAN; | ^^^^^^^^^^^^^ @@ -108,31 +180,31 @@ LL + !x.is_nan(); | warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:39:5 + --> $DIR/invalid-nan-comparison.rs:64:5 | LL | x < f64::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:41:5 + --> $DIR/invalid-nan-comparison.rs:66:5 | LL | x > f64::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:43:5 + --> $DIR/invalid-nan-comparison.rs:68:5 | LL | x <= f64::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:45:5 + --> $DIR/invalid-nan-comparison.rs:70:5 | LL | x >= f64::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:47:5 + --> $DIR/invalid-nan-comparison.rs:72:5 | LL | number!() == f64::NAN; | ^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +216,7 @@ LL + number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:49:5 + --> $DIR/invalid-nan-comparison.rs:74:5 | LL | f64::NAN != number!(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -155,5 +227,77 @@ LL - f64::NAN != number!(); LL + !number!().is_nan(); | -warning: 17 warnings emitted +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:81:5 + | +LL | x == f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x == f128::NAN; +LL + x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:83:5 + | +LL | x != f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x != f128::NAN; +LL + !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:85:5 + | +LL | x < f128::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:87:5 + | +LL | x > f128::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:89:5 + | +LL | x <= f128::NAN; + | ^^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:91:5 + | +LL | x >= f128::NAN; + | ^^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:93:5 + | +LL | number!() == f128::NAN; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - number!() == f128::NAN; +LL + number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:95:5 + | +LL | f128::NAN != number!(); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - f128::NAN != number!(); +LL + !number!().is_nan(); + | + +warning: 33 warnings emitted diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr index d88615186dd..6bc4501b6a3 100644 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will f LL | foo(_x); | ^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _x: () = return; + | ++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr index ec49137ba79..79f47bb5fbc 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail LL | false => <_>::default(), | ^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | false => <()>::default(), + | ~~ warning: this function depends on never type fallback being `()` --> $DIR/dependency-on-fallback-to-unit.rs:19:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail | LL | deserialize()?; | ^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | deserialize::<()>()?; + | ++++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index 2a3c5edc218..d40d1da76f9 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let x: (); + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-control-flow.rs:42:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail | LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | let x: (); + | ++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr index 11245cc7aab..d11c21d9573 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Test` will fail LL | unconstrained_arg(return); | ^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unconstrained_arg::<()>(return); + | ++++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr index b485c94df4d..30a5e60a758 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail LL | let _ = if true { unconstrained_return() } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _: () = if true { unconstrained_return() } else { panic!() }; + | ++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr index 3fb5536dee7..fb0166dd9e0 100644 --- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr +++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Bar` will fail LL | foo(|| panic!()); | ^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | foo::<(), _>(|| panic!()); + | +++++++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index a75039b8237..6a48a7b9b47 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -8,6 +8,10 @@ LL | unsafe { mem::zeroed() } = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { mem::zeroed::<()>() } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 @@ -18,6 +22,10 @@ LL | core::mem::transmute(Zst) = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | core::mem::transmute::<_, ()>(Zst) + | +++++++++ warning: never type fallback affects this union access --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 @@ -38,6 +46,10 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { *ptr::from_ref(&()).cast::<()>() } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 @@ -48,6 +60,10 @@ LL | unsafe { internally_create(x) } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { internally_create::<()>(x) } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 @@ -58,6 +74,10 @@ LL | unsafe { zeroed() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ warning: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 @@ -68,6 +88,10 @@ LL | let zeroed = mem::zeroed; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ warning: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 @@ -78,6 +102,10 @@ LL | let f = internally_create; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let f = internally_create::<()>; + | ++++++ warning: never type fallback affects this call to an `unsafe` method --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 @@ -102,6 +130,10 @@ LL | msg_send!(); = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `()` annotations to avoid fallback changes + | +LL | match send_message::<() /* ?0 */>() { + | ~~ warning: 10 warnings emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index 4138e9f8c86..844cd62c267 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -8,6 +8,10 @@ LL | unsafe { mem::zeroed() } = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { mem::zeroed::<()>() } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 @@ -18,6 +22,10 @@ LL | core::mem::transmute(Zst) = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | core::mem::transmute::<_, ()>(Zst) + | +++++++++ error: never type fallback affects this union access --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 @@ -38,6 +46,10 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { *ptr::from_ref(&()).cast::<()>() } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 @@ -48,6 +60,10 @@ LL | unsafe { internally_create(x) } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { internally_create::<()>(x) } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 @@ -58,6 +74,10 @@ LL | unsafe { zeroed() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ error: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 @@ -68,6 +88,10 @@ LL | let zeroed = mem::zeroed; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ error: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 @@ -78,6 +102,10 @@ LL | let f = internally_create; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let f = internally_create::<()>; + | ++++++ error: never type fallback affects this call to an `unsafe` method --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 @@ -102,6 +130,10 @@ LL | msg_send!(); = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `()` annotations to avoid fallback changes + | +LL | match send_message::<() /* ?0 */>() { + | ~~ warning: the type `!` does not permit zero-initialization --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 |
