"smallvec",
]
+[[package]]
+name = "measureme"
+version = "10.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd460fad6e55ca82fa0cd9dab0d315294188fd9ec6efbf4105e5635d4872ef9c"
+dependencies = [
+ "log",
+ "memmap2",
+ "parking_lot",
+ "perf-event-open-sys",
+ "rustc-hash",
+ "smallvec",
+]
+
[[package]]
name = "memchr"
version = "2.4.1"
"hex 0.4.2",
"libc",
"log",
- "measureme",
+ "measureme 9.1.2",
"rand 0.8.4",
"rustc-workspace-hack",
"rustc_version 0.4.0",
[[package]]
name = "proc-macro2"
-version = "1.0.24"
+version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
+checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
dependencies = [
"unicode-xid",
]
"indexmap",
"jobserver",
"libc",
- "measureme",
+ "measureme 9.1.2",
"memmap2",
"parking_lot",
"rustc-ap-rustc_graphviz",
"bitflags",
"cstr",
"libc",
- "measureme",
+ "measureme 10.0.0",
"rustc-demangle",
"rustc_arena",
"rustc_ast",
"indexmap",
"jobserver",
"libc",
- "measureme",
+ "measureme 10.0.0",
"memmap2",
"parking_lot",
"rustc-hash",
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
- "measureme",
+ "measureme 10.0.0",
"rustc-rayon-core",
"rustc_ast",
"rustc_data_structures",
[[package]]
name = "syn"
-version = "1.0.65"
+version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
+checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
dependencies = [
"proc-macro2",
"quote",
// TEMP = &foo
//
// so extract `temp`.
- let temp = if let Some(temp) = assigned_place.as_local() {
- temp
- } else {
+ let Some(temp) = assigned_place.as_local() else {
span_bug!(
self.body.source_info(start_location).span,
"expected 2-phase borrow to assign to a local, not `{:?}`",
let mut unified_already = FxHashSet::default();
for (fr, outlived) in &self.constraints_to_add {
- let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) {
- fr_name
- } else {
+ let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) else {
continue;
};
#![feature(format_args_capture)]
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(min_specialization)]
#![feature(stmt_expr_attributes)]
#![feature(trusted_step)]
bitflags = "1.0"
cstr = "0.2"
libc = "0.2"
-measureme = "9.1.0"
+measureme = "10.0.0"
snap = "1"
tracing = "0.1"
rustc_middle = { path = "../rustc_middle" }
_ => {}
}
}
- let fmts = match fmts {
- Some(f) => f,
- None => return Err("could not find formats for rlibs".to_string()),
+ let Some(fmts) = fmts else {
+ return Err("could not find formats for rlibs".to_string());
};
for &cnum in crates {
match fmts.get(cnum.as_usize() - 1) {
#![feature(box_patterns)]
#![feature(try_blocks)]
#![feature(in_band_lifetimes)]
+#![feature(let_else)]
#![feature(once_cell)]
#![feature(nll)]
#![feature(associated_type_bounds)]
.unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest))
.ty;
- let (llptr, llextra) = if let OperandValue::Ref(llptr, Some(llextra), _) = self {
- (llptr, llextra)
- } else {
+ let OperandValue::Ref(llptr, Some(llextra), _) = self else {
bug!("store_unsized called with a sized value")
};
#![feature(exact_size_is_empty)]
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(slice_ptr_get)]
Ok([..]) => {}
}
- let drop_trait = if let Some(did) = cx.tcx.lang_items().drop_trait() {
- did
- } else {
+ let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
// there is no way to define a type that needs non-const drop
// without having the lang item present.
return false;
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
rustc_index = { path = "../rustc_index", package = "rustc_index" }
bitflags = "1.2.1"
-measureme = "9.1.0"
+measureme = "10.0.0"
libc = "0.2"
stacker = "0.1.14"
tempfile = "3.2"
const FUNCTION_ARGS = 1 << 6;
const LLVM = 1 << 7;
const INCR_RESULT_HASHING = 1 << 8;
+ const ARTIFACT_SIZES = 1 << 9;
const DEFAULT = Self::GENERIC_ACTIVITIES.bits |
Self::QUERY_PROVIDERS.bits |
Self::QUERY_BLOCKED.bits |
Self::INCR_CACHE_LOADS.bits |
- Self::INCR_RESULT_HASHING.bits;
+ Self::INCR_RESULT_HASHING.bits |
+ Self::ARTIFACT_SIZES.bits;
const ARGS = Self::QUERY_KEYS.bits | Self::FUNCTION_ARGS.bits;
}
("args", EventFilter::ARGS),
("llvm", EventFilter::LLVM),
("incr-result-hashing", EventFilter::INCR_RESULT_HASHING),
+ ("artifact-sizes", EventFilter::ARTIFACT_SIZES),
];
/// Something that uniquely identifies a query invocation.
})
}
+ /// Record the size of an artifact that the compiler produces
+ ///
+ /// `artifact_kind` is the class of artifact (e.g., query_cache, object_file, etc.)
+ /// `artifact_name` is an identifier to the specific artifact being stored (usually a filename)
+ #[inline(always)]
+ pub fn artifact_size<A>(&self, artifact_kind: &str, artifact_name: A, size: u64)
+ where
+ A: Borrow<str> + Into<String>,
+ {
+ drop(self.exec(EventFilter::ARTIFACT_SIZES, |profiler| {
+ let builder = EventIdBuilder::new(&profiler.profiler);
+ let event_label = profiler.get_or_alloc_cached_string(artifact_kind);
+ let event_arg = profiler.get_or_alloc_cached_string(artifact_name);
+ let event_id = builder.from_label_and_arg(event_label, event_arg);
+ let thread_id = get_thread_id();
+
+ profiler.profiler.record_integer_event(
+ profiler.artifact_size_event_kind,
+ event_id,
+ thread_id,
+ size,
+ );
+
+ TimingGuard::none()
+ }))
+ }
+
#[inline(always)]
pub fn generic_activity_with_args(
&self,
) {
drop(self.exec(event_filter, |profiler| {
let event_id = StringId::new_virtual(query_invocation_id.0);
- let thread_id = std::thread::current().id().as_u64().get() as u32;
+ let thread_id = get_thread_id();
profiler.profiler.record_instant_event(
event_kind(profiler),
incremental_result_hashing_event_kind: StringId,
query_blocked_event_kind: StringId,
query_cache_hit_event_kind: StringId,
+ artifact_size_event_kind: StringId,
}
impl SelfProfiler {
profiler.alloc_string("IncrementalResultHashing");
let query_blocked_event_kind = profiler.alloc_string("QueryBlocked");
let query_cache_hit_event_kind = profiler.alloc_string("QueryCacheHit");
+ let artifact_size_event_kind = profiler.alloc_string("ArtifactSize");
let mut event_filter_mask = EventFilter::empty();
incremental_result_hashing_event_kind,
query_blocked_event_kind,
query_cache_hit_event_kind,
+ artifact_size_event_kind,
})
}
event_kind: StringId,
event_id: EventId,
) -> TimingGuard<'a> {
- let thread_id = std::thread::current().id().as_u64().get() as u32;
+ let thread_id = get_thread_id();
let raw_profiler = &profiler.profiler;
let timing_guard =
raw_profiler.start_recording_interval_event(event_kind, event_id, thread_id);
format!("{:.3}", dur.as_secs_f64())
}
+fn get_thread_id() -> u32 {
+ std::thread::current().id().as_u64().get() as u32
+}
+
// Memory reporting
cfg_if! {
if #[cfg(windows)] {
span: &mut MultiSpan,
children: &mut Vec<SubDiagnostic>,
) {
- let source_map = if let Some(ref sm) = source_map {
- sm
- } else {
- return;
- };
+ let Some(source_map) = source_map else { return };
debug!("fix_multispans_in_extern_macros: before: span={:?} children={:?}", span, children);
self.fix_multispan_in_extern_macros(source_map, span);
for child in children.iter_mut() {
#![feature(if_let_guard)]
#![feature(format_args_capture)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(nll)]
#[macro_use]
let mut undetermined_invocations = Vec::new();
let (mut progress, mut force) = (false, !self.monotonic);
loop {
- let (invoc, ext) = if let Some(invoc) = invocations.pop() {
- invoc
- } else {
+ let Some((invoc, ext)) = invocations.pop() else {
self.resolve_imports();
if undetermined_invocations.is_empty() {
break;
#![feature(format_args_capture)]
#![feature(if_let_guard)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_span)]
loop {
// Look at the last frame on the stack.
- let tree = if let Some(tree) = stack.last_mut().unwrap().next() {
- // If it still has a TokenTree we have not looked at yet, use that tree.
- tree
- } else {
+ // If it still has a TokenTree we have not looked at yet, use that tree.
+ let Some(tree) = stack.last_mut().unwrap().next() else {
// This else-case never produces a value for `tree` (it `continue`s or `return`s).
// Otherwise, if we have just reached the end of a sequence and we can keep repeating,
LockstepIterSize::Constraint(len, _) => {
// We do this to avoid an extra clone above. We know that this is a
// sequence already.
- let (sp, seq) = if let mbe::TokenTree::Sequence(sp, seq) = seq {
- (sp, seq)
- } else {
+ let mbe::TokenTree::Sequence(sp, seq) = seq else {
unreachable!()
};
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(in_band_lifetimes)]
+#![feature(let_else)]
#![feature(nll)]
#![recursion_limit = "256"]
return;
}
+ sess.prof.artifact_size(
+ &name.replace(' ', "_"),
+ path_buf.file_name().unwrap().to_string_lossy(),
+ encoder.position() as u64,
+ );
+
debug!("save: data written to disk successfully");
}
// have already tried before.
let source_directory = find_source_directory(&crate_dir, &source_directories_already_tried);
- let source_directory = if let Some(dir) = source_directory {
- dir
- } else {
+ let Some(source_directory) = source_directory else {
// There's nowhere to copy from, we're done
debug!(
"no source directory found. Continuing with empty session \
// We acquire a shared lock on the lock file of the directory, so that
// nobody deletes it out from under us while we are reading from it.
let lock_file_path = lock_file_path(source_dir);
- let _lock = if let Ok(lock) = flock::Lock::new(
+
+ // not exclusive
+ let Ok(_lock) = flock::Lock::new(
&lock_file_path,
false, // don't wait,
false, // don't create
false,
- ) {
- // not exclusive
- lock
- } else {
+ ) else {
// Could not acquire the lock, don't try to copy from here
return Err(());
};
match fn_return.kind {
TyKind::OpaqueDef(item_id, _) => {
let item = tcx.hir().item(item_id);
- let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
- opaque
- } else {
+ let ItemKind::OpaqueTy(opaque) = &item.kind else {
return;
};
#![feature(box_patterns)]
#![feature(extend_one)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(never_type)]
#![feature(in_band_lifetimes)]
#![feature(control_flow_enum)]
#![feature(crate_visibility_modifier)]
#![feature(drain_filter)]
#![feature(in_band_lifetimes)]
+#![feature(let_else)]
#![feature(nll)]
#![feature(once_cell)]
#![feature(proc_macro_internals)]
let len = BytePos::decode(decoder)?;
let hi = lo + len;
- let sess = if let Some(sess) = decoder.sess {
- sess
- } else {
+ let Some(sess) = decoder.sess else {
bug!("Cannot decode Span without Session.")
};
#![feature(new_uninit)]
#![feature(nll)]
#![feature(once_cell)]
+#![feature(let_else)]
#![feature(min_specialization)]
#![feature(trusted_len)]
#![feature(in_band_lifetimes)]
) -> bool {
let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
- let param = if let Some(param) = param {
- param
- } else {
+ let Some(param) = param else {
return false;
};
}
// Extract the number of elements from the layout of the array field:
- let len = if let Ok(TyAndLayout {
+ let Ok(TyAndLayout {
layout: Layout { fields: FieldsShape::Array { count, .. }, .. },
..
- }) = self.layout_of(f0_ty)
- {
- count
- } else {
+ }) = self.layout_of(f0_ty) else {
return Err(LayoutError::Unknown(ty));
};
- (*e_ty, *len, true)
+ (*e_ty, *count, true)
} else {
// First ADT field is not an array:
(f0_ty, def.non_enum_variant().fields.len() as _, false)
// Compute the ABI of the element type:
let e_ly = self.layout_of(e_ty)?;
- let e_abi = if let Abi::Scalar(scalar) = e_ly.abi {
- scalar
- } else {
+ let Abi::Scalar(e_abi) = e_ly.abi else {
// This error isn't caught in typeck, e.g., if
// the element type of the vector is generic.
tcx.sess.fatal(&format!(
let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local());
let closure_span = tcx.hir().span(closure_hir_id);
- let (capture_index, capture) = if let Some(capture_details) =
+ let Some((capture_index, capture)) =
find_capture_matching_projections(
typeck_results,
var_hir_id,
closure_def_id,
&from_builder.projection,
- ) {
- capture_details
- } else {
+ ) else {
if !enable_precise_capture(tcx, closure_span) {
bug!(
"No associated capture found for {:?}[{:#?}] even though \
blocks: &IndexVec<DropIdx, Option<BasicBlock>>,
) {
for (drop_idx, drop_data) in self.drops.iter_enumerated().rev() {
- let block = if let Some(block) = blocks[drop_idx] {
- block
- } else {
- continue;
- };
+ let Some(block) = blocks[drop_idx] else { continue };
match drop_data.0.kind {
DropKind::Value => {
let terminator = TerminatorKind::Drop {
#![feature(crate_visibility_modifier)]
#![feature(bool_to_option)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(once_cell)]
#![feature(min_specialization)]
#![recursion_limit = "256"]
#![feature(exact_size_is_empty)]
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(min_specialization)]
#![feature(once_cell)]
#![feature(stmt_expr_attributes)]
call: PeekCall,
) {
info!(?place, "peek_at");
- let local = if let Some(l) = place.as_local() {
- l
- } else {
+ let Some(local) = place.as_local() else {
tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
return;
};
call: PeekCall,
) {
info!(?place, "peek_at");
- let local = if let Some(l) = place.as_local() {
- l
- } else {
+ let Some(local) = place.as_local() else {
tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
return;
};
assert!(args.next().is_none());
let tuple = Place::from(tuple);
- let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_body, tcx).ty.kind() {
- s
- } else {
+ let ty::Tuple(tuple_tys) = tuple.ty(caller_body, tcx).ty.kind() else {
bug!("Closure arguments are not passed as a tuple");
};
#![cfg_attr(bootstrap, feature(const_panic))]
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(option_get_or_insert_default)]
pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let language_items = tcx.lang_items();
- let slice_len_fn_item_def_id = if let Some(slice_len_fn_item) = language_items.slice_len_fn() {
- slice_len_fn_item
- } else {
+ let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
// there is no language item to compare to :)
return;
};
operand,
cast_ty,
) => {
- let local = if let Some(local) = place.as_local() { local } else { return };
+ let Some(local) = place.as_local() else { return };
match operand {
Operand::Copy(place) | Operand::Move(place) => {
let operand_local =
}
}
Rvalue::Len(place) => {
- let local = if let Some(local) = place.local_or_deref_local() {
- local
- } else {
+ let Some(local) = place.local_or_deref_local() else {
return;
};
if let Some(cast_statement_idx) = state.get(&local).copied() {
let bb = BasicBlock::from_usize(bb);
trace!("processing block {:?}", bb);
- let discriminant_ty =
- if let Some(ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) {
- ty
- } else {
- continue;
- };
+ let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) else {
+ continue;
+ };
let layout = tcx.layout_of(tcx.param_env(body.source.def_id()).and(discriminant_ty));
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(control_flow_enum)]
+#![feature(let_else)]
#![feature(in_band_lifetimes)]
#![recursion_limit = "256"]
let is_generic = instance.substs.non_erasable_generics().next().is_some();
// Upstream `DefId` instances get different handling than local ones.
- let def_id = if let Some(def_id) = def_id.as_local() {
- def_id
- } else {
+ let Some(def_id) = def_id.as_local() else {
return if export_generics && is_generic {
// If it is an upstream monomorphization and we export generics, we must make
// it available to downstream crates.
doctest = false
[dependencies]
-measureme = "9.0.0"
+measureme = "10.0.0"
rustc-rayon-core = "0.3.1"
tracing = "0.1"
rustc_ast = { path = "../rustc_ast" }
index
}
- fn finish(self) -> FileEncodeResult {
+ fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
let Self { mut encoder, total_node_count, total_edge_count, result, stats: _ } = self;
let () = result?;
IntEncodedWithFixedSize(edge_count).encode(&mut encoder)?;
debug!("position: {:?}", encoder.position());
// Drop the encoder so that nothing is written after the counts.
- encoder.flush()
+ let result = encoder.flush();
+ // FIXME(rylev): we hardcode the dep graph file name so we don't need a dependency on
+ // rustc_incremental just for that.
+ profiler.artifact_size("dep_graph", "dep-graph.bin", encoder.position() as u64);
+ result
}
}
pub fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
let _prof_timer = profiler.generic_activity("incr_comp_encode_dep_graph");
- self.status.into_inner().finish()
+ self.status.into_inner().finish(profiler)
}
}
#![feature(core_intrinsics)]
#![feature(hash_raw_entry)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(min_specialization)]
#![feature(thread_local_const_init)]
if Some(i) == num_frames {
break;
}
- let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) {
- info
- } else {
+ let Some(query_info) = query_map.as_ref().and_then(|map| map.get(&query)) else {
break;
};
let mut diag = Diagnostic::new(
return false;
}
- let key = if let Some(key) =
+ let Some(key) =
<Q::Key as DepNodeParams<CTX::DepContext>>::recover(*tcx.dep_context(), &dep_node)
- {
- key
- } else {
+ else {
return false;
};
module: ModuleOrUniformRoot<'b>,
ident: Ident,
) -> Option<(Option<Suggestion>, Vec<String>)> {
- let mut crate_module = if let ModuleOrUniformRoot::Module(module) = module {
- module
- } else {
+ let ModuleOrUniformRoot::Module(mut crate_module) = module else {
return None;
};
match param.kind {
GenericParamKind::Lifetime { .. } => {
let (name, reg) = Region::early(&self.tcx.hir(), &mut index, ¶m);
- let def_id = if let Region::EarlyBound(_, def_id, _) = reg {
- def_id
- } else {
+ let Region::EarlyBound(_, def_id, _) = reg else {
bug!();
};
// We cannot predict what lifetimes are unused in opaque type.
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(never_type)]
#![feature(nll)]
#![recursion_limit = "256"]
"specify the events recorded by the self profiler;
for example: `-Z self-profile-events=default,query-keys`
all options: none, all, default, generic-activity, query-provider, query-cache-hit
- query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm"),
+ query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"),
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
"make the current crate share its generic instantiations"),
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
#![feature(hash_drain_filter)]
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(never_type)]
#![feature(crate_visibility_modifier)]
#![feature(control_flow_enum)]
let hir = self.tcx.hir();
let parent_node = hir.get_parent_node(obligation.cause.body_id);
let node = hir.find(parent_node);
- let (sig, body_id) = if let Some(hir::Node::Item(hir::Item {
+ let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(sig, _, body_id),
..
})) = node
- {
- (sig, body_id)
- } else {
+ else {
return false;
};
let body = hir.body(*body_id);
debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty);
let traits = (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait());
- let (unsize_did, dispatch_from_dyn_did) = if let (Some(u), Some(cu)) = traits {
- (u, cu)
- } else {
+ let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits");
return false;
};
) -> Result<Option<Self>, ErrorReported> {
let attrs = tcx.get_attrs(impl_def_id);
- let attr = if let Some(item) = tcx.sess.find_by_name(&attrs, sym::rustc_on_unimplemented) {
- item
- } else {
+ let Some(attr) = tcx.sess.find_by_name(&attrs, sym::rustc_on_unimplemented) else {
return Ok(None);
};
cause.clone(),
);
- let data = if let ty::Dynamic(ref data, ..) = normalized_ty.kind() {
- data
- } else {
+ let ty::Dynamic(data, ..) = normalized_ty.kind() else {
return None;
};
debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id);
- let self_ty = if let Some(ty) = opt_self_ty {
- ty
- } else {
+ let Some(self_ty) = opt_self_ty else {
let path_str = tcx.def_path_str(trait_def_id);
let def_id = self.item_def_id();
let traits =
(self.tcx.lang_items().unsize_trait(), self.tcx.lang_items().coerce_unsized_trait());
- let (unsize_did, coerce_unsized_did) = if let (Some(u), Some(cu)) = traits {
- (u, cu)
- } else {
+ let (Some(unsize_did), Some(coerce_unsized_did)) = traits else {
debug!("missing Unsize or CoerceUnsized traits");
return Err(TypeError::Mismatch);
};
return false;
}
- let src = if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
- src
- } else {
+ let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) else {
return false;
};
// FIXME: Instead of exiting early when encountering bound vars in
// the function signature, consider keeping the binder here and
// propagating it downwards.
- let fn_sig = if let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() {
- fn_sig
- } else {
+ let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() else {
return false;
};
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
// Resolve the path and check the definition for errors.
- let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
- {
- variant_ty
- } else {
+ let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
let err = self.tcx.ty_error();
for field in fields {
let ti = TopInfo { parent_pat: Some(pat), ..ti };
debug!("convert_place_op_to_mutable: method={:?}", method);
self.write_method_call(expr.hir_id, method);
- let region = if let ty::Ref(r, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() {
- r
- } else {
+ let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else {
span_bug!(expr.span, "input to mutable place op is not a mut ref?");
};
return None;
}
- let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
- min_captures.and_then(|m| m.get(&var_hir_id))
- {
- root_var_min_capture_list
- } else {
+ let Some(root_var_min_capture_list) = min_captures.and_then(|m| m.get(&var_hir_id)) else {
// The upvar is mentioned within the closure but no path starting from it is
// used.
closure_clause: hir::CaptureBy,
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
) -> (Vec<MigrationDiagnosticInfo>, String) {
- let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
- upvars
- } else {
+ let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) else {
return (Vec::new(), format!(""));
};
diag_expr_id: hir::HirId,
) {
let tcx = self.fcx.tcx;
- let upvar_id = if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
- upvar_id
- } else {
+ let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else {
return;
};
#![feature(in_band_lifetimes)]
#![feature(is_sorted)]
#![feature(iter_zip)]
+#![feature(let_else)]
#![feature(min_specialization)]
#![feature(nll)]
#![feature(try_blocks)]
use crate::num::flt2dec;
use crate::num::fmt as numfmt;
+#[doc(hidden)]
+trait GeneralFormat: PartialOrd {
+ /// Determines if a value should use exponential based on its magnitude, given the precondition
+ /// that it will not be rounded any further before it is displayed.
+ fn already_rounded_value_should_use_exponential(&self) -> bool;
+}
+
+macro_rules! impl_general_format {
+ ($($t:ident)*) => {
+ $(impl GeneralFormat for $t {
+ fn already_rounded_value_should_use_exponential(&self) -> bool {
+ let abs = $t::abs_private(*self);
+ (abs != 0.0 && abs < 1e-4) || abs >= 1e+16
+ }
+ })*
+ }
+}
+
+impl_general_format! { f32 f64 }
+
// Don't inline this so callers don't use the stack space this function
// requires unless they have to.
#[inline(never)]
fmt.pad_formatted_parts(&formatted)
}
-// Common code of floating point Debug and Display.
-fn float_to_decimal_common<T>(fmt: &mut Formatter<'_>, num: &T, min_precision: usize) -> Result
+fn float_to_decimal_display<T>(fmt: &mut Formatter<'_>, num: &T) -> Result
where
T: flt2dec::DecodableFloat,
{
if let Some(precision) = fmt.precision {
float_to_decimal_common_exact(fmt, num, sign, precision)
} else {
+ let min_precision = 0;
float_to_decimal_common_shortest(fmt, num, sign, min_precision)
}
}
}
}
+fn float_to_general_debug<T>(fmt: &mut Formatter<'_>, num: &T) -> Result
+where
+ T: flt2dec::DecodableFloat + GeneralFormat,
+{
+ let force_sign = fmt.sign_plus();
+ let sign = match force_sign {
+ false => flt2dec::Sign::Minus,
+ true => flt2dec::Sign::MinusPlus,
+ };
+
+ if let Some(precision) = fmt.precision {
+ // this behavior of {:.PREC?} predates exponential formatting for {:?}
+ float_to_decimal_common_exact(fmt, num, sign, precision)
+ } else {
+ // since there is no precision, there will be no rounding
+ if num.already_rounded_value_should_use_exponential() {
+ let upper = false;
+ float_to_exponential_common_shortest(fmt, num, sign, upper)
+ } else {
+ let min_precision = 1;
+ float_to_decimal_common_shortest(fmt, num, sign, min_precision)
+ }
+ }
+}
+
macro_rules! floating {
($ty:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for $ty {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
- float_to_decimal_common(fmt, self, 1)
+ float_to_general_debug(fmt, self)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Display for $ty {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
- float_to_decimal_common(fmt, self, 0)
+ float_to_decimal_display(fmt, self)
}
}
// private use internally.
#[inline]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
- const fn abs_private(self) -> f32 {
+ pub(crate) const fn abs_private(self) -> f32 {
f32::from_bits(self.to_bits() & 0x7fff_ffff)
}
// private use internally.
#[inline]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
- const fn abs_private(self) -> f64 {
+ pub(crate) const fn abs_private(self) -> f64 {
f64::from_bits(self.to_bits() & 0x7fff_ffff_ffff_ffff)
}
assert_eq!("1.23456789E3", format!("{:E}", 1234.56789f64));
assert_eq!("0.0", format!("{:?}", 0.0f64));
assert_eq!("1.01", format!("{:?}", 1.01f64));
+
+ let high_cutoff = 1e16_f64;
+ assert_eq!("1e16", format!("{:?}", high_cutoff));
+ assert_eq!("-1e16", format!("{:?}", -high_cutoff));
+ assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f64::EPSILON))));
+ assert_eq!("-3.0", format!("{:?}", -3f64));
+ assert_eq!("0.0001", format!("{:?}", 0.0001f64));
+ assert_eq!("9e-5", format!("{:?}", 0.00009f64));
+ assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f64));
+ assert_eq!("1234.6", format!("{:.1?}", 1234.56789f64));
}
#[test]
assert_eq!("1.2345679E3", format!("{:E}", 1234.56789f32));
assert_eq!("0.0", format!("{:?}", 0.0f32));
assert_eq!("1.01", format!("{:?}", 1.01f32));
+
+ let high_cutoff = 1e16_f32;
+ assert_eq!("1e16", format!("{:?}", high_cutoff));
+ assert_eq!("-1e16", format!("{:?}", -high_cutoff));
+ assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f32::EPSILON))));
+ assert_eq!("-3.0", format!("{:?}", -3f32));
+ assert_eq!("0.0001", format!("{:?}", 0.0001f32));
+ assert_eq!("9e-5", format!("{:?}", 0.00009f32));
+ assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f32));
+ assert_eq!("1234.6", format!("{:.1?}", 1234.56789f32));
+}
+
+fn is_exponential(s: &str) -> bool {
+ s.contains("e") || s.contains("E")
}
-Subproject commit c7957a74bdcf3b11e7154c1a9401735f23ebd484
+Subproject commit 7fbbf4e8f23e3c24b8afff541dcb17e53eb5ff88