Auto merge of #132470 - GuillaumeGomez:rollup-1a1mkmp, r=GuillaumeGomez
Rollup of 14 pull requests Successful merges: - #131829 (Remove support for `-Zprofile` (gcov-style coverage instrumentation)) - #132369 (style-guide: Only use the new binop heuristic for assignments) - #132383 (Implement suggestion for never type fallback lints) - #132413 (update offset_of! docs to reflect the stabilization of nesting) - #132438 (Remove unncessary option for default rust-analyzer setting) - #132439 (Add `f16` and `f128` to `invalid_nan_comparison`) - #132444 (rustdoc: Directly use rustc_abi instead of reexports) - #132445 (Cleanup attributes around unchecked shifts and unchecked negation in const) - #132448 (Add missing backtick) - #132450 (Show actual MIR when MIR building forgot to terminate block) - #132451 (remove some unnecessary rustc_allow_const_fn_unstable) - #132455 (make const_alloc_layout feature gate only about functions that are already stable) - #132456 (Move remaining inline assembly test files into asm directory) - #132459 (feat(byte_sub_ptr): unstably add ptr::byte_sub_ptr) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7c7bb7dc01
@ -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
|
||||
|
@ -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,
|
||||
|
@ -7,7 +7,6 @@
|
||||
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`.
|
||||
|
@ -55,7 +55,6 @@
|
||||
|
||||
/// 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 @@ pub(crate) fn new(llmod: &'ll llvm::Module) -> Self {
|
||||
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(),
|
||||
|
@ -2269,7 +2269,6 @@ pub fn LLVMRustOptimize<'a>(
|
||||
PGOUsePath: *const c_char,
|
||||
InstrumentCoverage: bool,
|
||||
InstrProfileOutput: *const c_char,
|
||||
InstrumentGCOV: bool,
|
||||
PGOSampleUsePath: *const c_char,
|
||||
DebugInfoForProfiling: bool,
|
||||
llvm_selfprofiler: *mut c_void,
|
||||
|
@ -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 @@ macro_rules! if_regular {
|
||||
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();
|
||||
|
@ -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)]
|
||||
|
@ -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_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 @@ fn calculate_diverging_fallback(
|
||||
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 @@ fn lint_never_type_fallback_flowing_into_unsafe_code(
|
||||
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 @@ fn lint_never_type_fallback_flowing_into_unsafe_code(
|
||||
.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::UnionField => {
|
||||
errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField
|
||||
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 {
|
||||
sugg: sugg.clone(),
|
||||
}
|
||||
}
|
||||
UnsafeUseReason::Deref => {
|
||||
errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { sugg: sugg.clone() }
|
||||
}
|
||||
UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref,
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -451,6 +471,7 @@ fn lint_obligations_broken_by_never_type_fallback_change(
|
||||
&self,
|
||||
behavior: DivergingFallbackBehavior,
|
||||
diverging_vids: &[ty::TyVid],
|
||||
coercions: &VecGraph<ty::TyVid, true>,
|
||||
) {
|
||||
let DivergingFallbackBehavior::ToUnit = behavior else { return };
|
||||
|
||||
@ -478,13 +499,14 @@ fn lint_obligations_broken_by_never_type_fallback_change(
|
||||
};
|
||||
|
||||
// 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 @@ fn lint_obligations_broken_by_never_type_fallback_change(
|
||||
errors::DependencyOnUnitNeverTypeFallback {
|
||||
obligation_span: never_error.obligation.cause.span,
|
||||
obligation: never_error.obligation.predicate,
|
||||
sugg,
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -541,6 +564,153 @@ fn create_coercion_graph(&self) -> VecGraph<ty::TyVid, true> {
|
||||
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 visit_expr(&mut self, ex: &'_ hir::Expr<'_>) {
|
||||
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 visit_expr(&mut self, ex: &'_ hir::Expr<'_>) {
|
||||
// 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 visit_ty(&mut self, t: Ty<'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:?}");
|
||||
|
||||
|
@ -832,8 +832,6 @@ macro_rules! tracked {
|
||||
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));
|
||||
|
@ -204,7 +204,10 @@ fn is_nan(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||
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,
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -778,9 +778,7 @@ fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -762,32 +762,34 @@ fn write_basic_block<'tcx, F>(
|
||||
|
||||
// Terminator at the bottom.
|
||||
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
||||
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
|
||||
if options.include_extra_comments {
|
||||
writeln!(
|
||||
w,
|
||||
"{:A$} // {}{}",
|
||||
indented_terminator,
|
||||
if tcx.sess.verbose_internals() {
|
||||
format!("{current_location:?}: ")
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
comment(tcx, data.terminator().source_info),
|
||||
A = ALIGN,
|
||||
)?;
|
||||
} else {
|
||||
writeln!(w, "{indented_terminator}")?;
|
||||
}
|
||||
if data.terminator.is_some() {
|
||||
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
|
||||
if options.include_extra_comments {
|
||||
writeln!(
|
||||
w,
|
||||
"{:A$} // {}{}",
|
||||
indented_terminator,
|
||||
if tcx.sess.verbose_internals() {
|
||||
format!("{current_location:?}: ")
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
comment(tcx, data.terminator().source_info),
|
||||
A = ALIGN,
|
||||
)?;
|
||||
} else {
|
||||
writeln!(w, "{indented_terminator}")?;
|
||||
}
|
||||
|
||||
write_extra(
|
||||
tcx,
|
||||
w,
|
||||
|visitor| {
|
||||
visitor.visit_terminator(data.terminator(), current_location);
|
||||
},
|
||||
options,
|
||||
)?;
|
||||
write_extra(
|
||||
tcx,
|
||||
w,
|
||||
|visitor| {
|
||||
visitor.visit_terminator(data.terminator(), current_location);
|
||||
},
|
||||
options,
|
||||
)?;
|
||||
}
|
||||
|
||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||
extra_data(PassWhere::AfterTerminator(block), w)?;
|
||||
|
@ -791,12 +791,6 @@ fn new(
|
||||
}
|
||||
|
||||
fn finish(self) -> Body<'tcx> {
|
||||
for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
|
||||
if block.terminator.is_none() {
|
||||
span_bug!(self.fn_span, "no terminator on block {:?}", index);
|
||||
}
|
||||
}
|
||||
|
||||
let mut body = Body::new(
|
||||
MirSource::item(self.def_id.to_def_id()),
|
||||
self.cfg.basic_blocks,
|
||||
@ -810,6 +804,23 @@ fn finish(self) -> Body<'tcx> {
|
||||
None,
|
||||
);
|
||||
body.coverage_info_hi = self.coverage_info.map(|b| b.into_done());
|
||||
|
||||
for (index, block) in body.basic_blocks.iter().enumerate() {
|
||||
if block.terminator.is_none() {
|
||||
use rustc_middle::mir::pretty;
|
||||
let options = pretty::PrettyPrintMirOptions::from_cli(self.tcx);
|
||||
pretty::write_mir_fn(
|
||||
self.tcx,
|
||||
&body,
|
||||
&mut |_, _| Ok(()),
|
||||
&mut std::io::stdout(),
|
||||
options,
|
||||
)
|
||||
.unwrap();
|
||||
span_bug!(self.fn_span, "no terminator on block {:?}", index);
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -1985,13 +1985,8 @@ pub(crate) fn parse_mir_include_spans(slot: &mut MirIncludeSpans, v: Option<&str
|
||||
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],
|
||||
|
@ -216,7 +216,7 @@ pub const fn for_value<T: ?Sized>(t: &T) -> Self {
|
||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")]
|
||||
#[must_use]
|
||||
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
|
||||
// SAFETY: we pass along the prerequisites of these functions to the caller
|
||||
@ -232,7 +232,6 @@ pub const fn for_value<T: ?Sized>(t: &T) -> Self {
|
||||
/// sentinel value. Types that lazily allocate must track initialization by
|
||||
/// some other means.
|
||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn dangling(&self) -> NonNull<u8> {
|
||||
@ -256,6 +255,7 @@ pub const fn dangling(&self) -> NonNull<u8> {
|
||||
/// `align` violates the conditions listed in [`Layout::from_size_align`].
|
||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
|
||||
#[inline]
|
||||
pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
|
||||
if let Some(align) = Alignment::new(align) {
|
||||
@ -282,7 +282,6 @@ pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
|
||||
/// address for the whole allocated block of memory. One way to
|
||||
/// satisfy this constraint is to ensure `align <= self.align()`.
|
||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[must_use = "this returns the padding needed, \
|
||||
without modifying the `Layout`"]
|
||||
#[inline]
|
||||
@ -332,6 +331,7 @@ const fn size_rounded_up_to_custom_align(&self, align: Alignment) -> usize {
|
||||
/// to the layout's current size.
|
||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
|
||||
#[must_use = "this returns a new `Layout`, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
@ -374,7 +374,6 @@ pub const fn pad_to_align(&self) -> Layout {
|
||||
/// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8));
|
||||
/// ```
|
||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[inline]
|
||||
pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
|
||||
let padded = self.pad_to_align();
|
||||
@ -432,6 +431,7 @@ pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
|
||||
/// ```
|
||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
|
||||
#[inline]
|
||||
pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
|
||||
let new_align = Alignment::max(self.align, next.align);
|
||||
@ -463,7 +463,6 @@ pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
|
||||
///
|
||||
/// On arithmetic overflow, returns `LayoutError`.
|
||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[inline]
|
||||
pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
|
||||
if let Some(size) = self.size.checked_mul(n) {
|
||||
@ -481,7 +480,6 @@ pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
|
||||
///
|
||||
/// On arithmetic overflow, returns `LayoutError`.
|
||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[inline]
|
||||
pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
|
||||
// SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the
|
||||
@ -497,6 +495,7 @@ pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
|
||||
/// `isize::MAX`, returns `LayoutError`.
|
||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
|
||||
#[inline]
|
||||
pub const fn array<T>(n: usize) -> Result<Self, LayoutError> {
|
||||
// Reduce the amount of code we need to monomorphize per `T`.
|
||||
|
@ -390,9 +390,6 @@ pub const fn uninit() -> MaybeUninit<T> {
|
||||
#[must_use]
|
||||
#[rustc_diagnostic_item = "maybe_uninit_zeroed"]
|
||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||
// These are OK to allow since we do not leak &mut to user-visible API
|
||||
#[rustc_allow_const_fn_unstable(const_mut_refs)]
|
||||
#[rustc_allow_const_fn_unstable(const_ptr_write)]
|
||||
#[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")]
|
||||
pub const fn zeroed() -> MaybeUninit<T> {
|
||||
let mut u = MaybeUninit::<T>::uninit();
|
||||
|
@ -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:
|
||||
///
|
||||
|
@ -1161,7 +1161,7 @@ pub const fn checked_neg(self) -> Option<Self> {
|
||||
)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[rustc_const_unstable(feature = "unchecked_neg", issue = "85122")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_neg", issue = "85122"))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_neg(self) -> Self {
|
||||
@ -1227,8 +1227,7 @@ pub const fn strict_neg(self) -> Self {
|
||||
/// ```
|
||||
#[stable(feature = "wrapping", since = "1.7.0")]
|
||||
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
|
||||
// We could always go back to wrapping
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
@ -1294,7 +1293,7 @@ pub const fn strict_shl(self, rhs: u32) -> Self {
|
||||
)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
|
||||
@ -1353,8 +1352,7 @@ pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
|
||||
/// ```
|
||||
#[stable(feature = "wrapping", since = "1.7.0")]
|
||||
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
|
||||
// We could always go back to wrapping
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
@ -1420,7 +1418,7 @@ pub const fn strict_shr(self, rhs: u32) -> Self {
|
||||
)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
|
||||
@ -2151,7 +2149,7 @@ pub const fn wrapping_neg(self) -> Self {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline(always)]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
pub const fn wrapping_shl(self, rhs: u32) -> Self {
|
||||
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
|
||||
// out of bounds
|
||||
@ -2181,7 +2179,7 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline(always)]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
pub const fn wrapping_shr(self, rhs: u32) -> Self {
|
||||
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
|
||||
// out of bounds
|
||||
|
@ -1475,7 +1475,6 @@ pub const fn ilog10(self) -> u32 {
|
||||
/// ```
|
||||
#[unstable(feature = "num_midpoint", issue = "110840")]
|
||||
#[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
|
||||
#[rustc_allow_const_fn_unstable(const_num_midpoint)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
|
@ -1416,8 +1416,7 @@ pub const fn strict_neg(self) -> Self {
|
||||
/// ```
|
||||
#[stable(feature = "wrapping", since = "1.7.0")]
|
||||
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
|
||||
// We could always go back to wrapping
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
@ -1483,7 +1482,7 @@ pub const fn strict_shl(self, rhs: u32) -> Self {
|
||||
)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
|
||||
@ -1542,8 +1541,7 @@ pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
|
||||
/// ```
|
||||
#[stable(feature = "wrapping", since = "1.7.0")]
|
||||
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
|
||||
// We could always go back to wrapping
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
@ -1609,7 +1607,7 @@ pub const fn strict_shr(self, rhs: u32) -> Self {
|
||||
)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
|
||||
@ -2132,7 +2130,7 @@ pub const fn wrapping_neg(self) -> Self {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline(always)]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
pub const fn wrapping_shl(self, rhs: u32) -> Self {
|
||||
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
|
||||
// out of bounds
|
||||
@ -2165,7 +2163,7 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline(always)]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
|
||||
pub const fn wrapping_shr(self, rhs: u32) -> Self {
|
||||
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
|
||||
// out of bounds
|
||||
|
@ -582,7 +582,7 @@ pub fn mask(self, mask: usize) -> *const T {
|
||||
intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers. The returned value is in
|
||||
/// Calculates the distance between two pointers within the same allocation. The returned value is in
|
||||
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
|
||||
///
|
||||
/// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
|
||||
@ -677,7 +677,7 @@ pub fn mask(self, mask: usize) -> *const T {
|
||||
unsafe { intrinsics::ptr_offset_from(self, origin) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers. The returned value is in
|
||||
/// Calculates the distance between two pointers within the same allocation. The returned value is in
|
||||
/// units of **bytes**.
|
||||
///
|
||||
/// This is purely a convenience for casting to a `u8` pointer and
|
||||
@ -695,7 +695,7 @@ pub fn mask(self, mask: usize) -> *const T {
|
||||
unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers, *where it's known that
|
||||
/// Calculates the distance between two pointers within the same allocation, *where it's known that
|
||||
/// `self` is equal to or greater than `origin`*. The returned value is in
|
||||
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
|
||||
///
|
||||
@ -790,6 +790,25 @@ const fn comptime(_: *const (), _: *const ()) -> bool {
|
||||
unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers within the same allocation, *where it's known that
|
||||
/// `self` is equal to or greater than `origin`*. The returned value is in
|
||||
/// units of **bytes**.
|
||||
///
|
||||
/// This is purely a convenience for casting to a `u8` pointer and
|
||||
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
|
||||
/// documentation and safety requirements.
|
||||
///
|
||||
/// For non-`Sized` pointees this operation considers only the data pointers,
|
||||
/// ignoring the metadata.
|
||||
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
|
||||
#[inline]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *const U) -> usize {
|
||||
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
|
||||
unsafe { self.cast::<u8>().sub_ptr(origin.cast::<u8>()) }
|
||||
}
|
||||
|
||||
/// Returns whether two pointers are guaranteed to be equal.
|
||||
///
|
||||
/// At runtime this function behaves like `Some(self == other)`.
|
||||
@ -1005,7 +1024,7 @@ const fn comptime(_: *const (), _: usize, _: usize) -> bool {
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_neg)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn sub(self, count: usize) -> Self
|
||||
|
@ -844,7 +844,6 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
|
||||
#[must_use]
|
||||
#[stable(feature = "ptr_from_ref", since = "1.76.0")]
|
||||
#[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_mut_refs)]
|
||||
#[rustc_never_returns_null_ptr]
|
||||
pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
|
||||
r
|
||||
|
@ -746,7 +746,7 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
|
||||
(self as *const T).guaranteed_ne(other as _)
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers. The returned value is in
|
||||
/// Calculates the distance between two pointers within the same allocation. The returned value is in
|
||||
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
|
||||
///
|
||||
/// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
|
||||
@ -839,7 +839,7 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
|
||||
unsafe { (self as *const T).offset_from(origin) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers. The returned value is in
|
||||
/// Calculates the distance between two pointers within the same allocation. The returned value is in
|
||||
/// units of **bytes**.
|
||||
///
|
||||
/// This is purely a convenience for casting to a `u8` pointer and
|
||||
@ -857,7 +857,7 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
|
||||
unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers, *where it's known that
|
||||
/// Calculates the distance between two pointers within the same allocation, *where it's known that
|
||||
/// `self` is equal to or greater than `origin`*. The returned value is in
|
||||
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
|
||||
///
|
||||
@ -930,6 +930,25 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
|
||||
unsafe { (self as *const T).sub_ptr(origin) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers within the same allocation, *where it's known that
|
||||
/// `self` is equal to or greater than `origin`*. The returned value is in
|
||||
/// units of **bytes**.
|
||||
///
|
||||
/// This is purely a convenience for casting to a `u8` pointer and
|
||||
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
|
||||
/// documentation and safety requirements.
|
||||
///
|
||||
/// For non-`Sized` pointees this operation considers only the data pointers,
|
||||
/// ignoring the metadata.
|
||||
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
|
||||
#[inline]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *mut U) -> usize {
|
||||
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
|
||||
unsafe { (self as *const T).byte_sub_ptr(origin) }
|
||||
}
|
||||
|
||||
/// Adds an unsigned offset to a pointer.
|
||||
///
|
||||
/// This can only move the pointer forward (or not move it). If you need to move forward or
|
||||
@ -1085,7 +1104,7 @@ const fn comptime(_: *const (), _: usize, _: usize) -> bool {
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_neg)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn sub(self, count: usize) -> Self
|
||||
|
@ -635,7 +635,7 @@ pub const fn cast<U>(self) -> NonNull<U> {
|
||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
||||
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
|
||||
#[rustc_allow_const_fn_unstable(unchecked_neg)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
|
||||
pub const unsafe fn sub(self, count: usize) -> Self
|
||||
where
|
||||
T: Sized,
|
||||
@ -676,7 +676,7 @@ pub const fn cast<U>(self) -> NonNull<U> {
|
||||
unsafe { NonNull { pointer: self.pointer.byte_sub(count) } }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers. The returned value is in
|
||||
/// Calculates the distance between two pointers within the same allocation. The returned value is in
|
||||
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
|
||||
///
|
||||
/// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
|
||||
@ -773,7 +773,7 @@ pub const fn cast<U>(self) -> NonNull<U> {
|
||||
unsafe { self.pointer.offset_from(origin.pointer) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers. The returned value is in
|
||||
/// Calculates the distance between two pointers within the same allocation. The returned value is in
|
||||
/// units of **bytes**.
|
||||
///
|
||||
/// This is purely a convenience for casting to a `u8` pointer and
|
||||
@ -793,7 +793,7 @@ pub const fn cast<U>(self) -> NonNull<U> {
|
||||
|
||||
// N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
|
||||
|
||||
/// Calculates the distance between two pointers, *where it's known that
|
||||
/// Calculates the distance between two pointers within the same allocation, *where it's known that
|
||||
/// `self` is equal to or greater than `origin`*. The returned value is in
|
||||
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
|
||||
///
|
||||
@ -866,6 +866,25 @@ pub const fn cast<U>(self) -> NonNull<U> {
|
||||
unsafe { self.pointer.sub_ptr(subtracted.pointer) }
|
||||
}
|
||||
|
||||
/// Calculates the distance between two pointers within the same allocation, *where it's known that
|
||||
/// `self` is equal to or greater than `origin`*. The returned value is in
|
||||
/// units of **bytes**.
|
||||
///
|
||||
/// This is purely a convenience for casting to a `u8` pointer and
|
||||
/// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for
|
||||
/// documentation and safety requirements.
|
||||
///
|
||||
/// For non-`Sized` pointees this operation considers only the data pointers,
|
||||
/// ignoring the metadata.
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
|
||||
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
|
||||
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
|
||||
unsafe { self.pointer.byte_sub_ptr(origin.pointer) }
|
||||
}
|
||||
|
||||
/// Reads the value from `self` without moving it. This leaves the
|
||||
/// memory in `self` unchanged.
|
||||
///
|
||||
|
@ -764,7 +764,6 @@ pub const fn as_ptr(&self) -> *const T {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_mut_refs)]
|
||||
#[rustc_never_returns_null_ptr]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
@ -1867,7 +1866,6 @@ pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")]
|
||||
#[rustc_allow_const_fn_unstable(split_at_checked)]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
|
@ -761,7 +761,6 @@ pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
|
||||
#[must_use]
|
||||
#[stable(feature = "split_at_checked", since = "1.80.0")]
|
||||
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
|
||||
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
|
||||
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(mid) {
|
||||
|
@ -571,6 +571,7 @@ fn hashes(&self) -> Vec<&str> {
|
||||
"b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a",
|
||||
"828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000",
|
||||
"811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d",
|
||||
"4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
|
||||
],
|
||||
EditorKind::Emacs => vec![
|
||||
"51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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".
|
||||
|
@ -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 {
|
||||
@ -341,12 +341,6 @@ impl SomeType {
|
||||
.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
|
||||
+ 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")
|
||||
|
@ -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.
|
@ -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",
|
||||
|
@ -5,6 +5,7 @@
|
||||
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_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 @@ fn build_fn_header(
|
||||
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)]
|
||||
|
@ -13,6 +13,7 @@
|
||||
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_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 @@ pub(crate) fn print<'a, 'tcx: 'a>(
|
||||
}
|
||||
}
|
||||
|
||||
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()),
|
||||
}
|
||||
})
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
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_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;
|
||||
|
@ -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;
|
||||
|
@ -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_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()),
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
@ -1 +0,0 @@
|
||||
fn main() {}
|
@ -23,7 +23,7 @@ const fn foo() { [()][42] }
|
||||
13
|
||||
}
|
||||
|
||||
// We do not promote union field accesses in `fn.
|
||||
// We do not promote union field accesses in `fn`.
|
||||
union U { x: i32, y: i32 }
|
||||
pub const fn promote_union() {
|
||||
let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,10 +1,34 @@
|
||||
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 == 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;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(invalid_nan_comparisons)]` on by default
|
||||
help: use `f32::is_nan()` or `f64::is_nan()` instead
|
||||
|
|
||||
LL - let _ = x == f32::NAN;
|
||||
@ -12,7 +36,7 @@ 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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user