Auto merge of #89933 - est31:let_else, r=michaelwoerister
Adopt let_else across the compiler This performs a substitution of code following the pattern: ``` let <id> = if let <pat> = ... { identity } else { ... : ! }; ``` To simplify it to: ``` let <pat> = ... { identity } else { ... : ! }; ``` By adopting the `let_else` feature (cc #87335). The PR also updates the syn crate because the currently used version of the crate doesn't support `let_else` syntax yet. Note: Generally I'm the person who *removes* usages of unstable features from the compiler, not adds more usages of them, but in this instance I think it hopefully helps the feature get stabilized sooner and in a better state. I have written a [comment](https://github.com/rust-lang/rust/issues/87335#issuecomment-944846205) on the tracking issue about my experience and what I feel could be improved before stabilization of `let_else`.
This commit is contained in:
commit
1af55d19c7
54 changed files with 76 additions and 150 deletions
|
@ -2728,9 +2728,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.24"
|
version = "1.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
@ -5093,9 +5093,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.65"
|
version = "1.0.80"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
|
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -315,9 +315,7 @@ impl<'a, 'tcx> GatherBorrows<'a, 'tcx> {
|
||||||
// TEMP = &foo
|
// TEMP = &foo
|
||||||
//
|
//
|
||||||
// so extract `temp`.
|
// so extract `temp`.
|
||||||
let temp = if let Some(temp) = assigned_place.as_local() {
|
let Some(temp) = assigned_place.as_local() else {
|
||||||
temp
|
|
||||||
} else {
|
|
||||||
span_bug!(
|
span_bug!(
|
||||||
self.body.source_info(start_location).span,
|
self.body.source_info(start_location).span,
|
||||||
"expected 2-phase borrow to assign to a local, not `{:?}`",
|
"expected 2-phase borrow to assign to a local, not `{:?}`",
|
||||||
|
|
|
@ -90,9 +90,7 @@ impl OutlivesSuggestionBuilder {
|
||||||
let mut unified_already = FxHashSet::default();
|
let mut unified_already = FxHashSet::default();
|
||||||
|
|
||||||
for (fr, outlived) in &self.constraints_to_add {
|
for (fr, outlived) in &self.constraints_to_add {
|
||||||
let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) {
|
let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) else {
|
||||||
fr_name
|
|
||||||
} else {
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#![feature(format_args_capture)]
|
#![feature(format_args_capture)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(trusted_step)]
|
#![feature(trusted_step)]
|
||||||
|
|
|
@ -174,9 +174,8 @@ pub fn each_linked_rlib(
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let fmts = match fmts {
|
let Some(fmts) = fmts else {
|
||||||
Some(f) => f,
|
return Err("could not find formats for rlibs".to_string());
|
||||||
None => return Err("could not find formats for rlibs".to_string()),
|
|
||||||
};
|
};
|
||||||
for &cnum in crates {
|
for &cnum in crates {
|
||||||
match fmts.get(cnum.as_usize() - 1) {
|
match fmts.get(cnum.as_usize() - 1) {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
|
|
|
@ -343,9 +343,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
|
||||||
.unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest))
|
.unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest))
|
||||||
.ty;
|
.ty;
|
||||||
|
|
||||||
let (llptr, llextra) = if let OperandValue::Ref(llptr, Some(llextra), _) = self {
|
let OperandValue::Ref(llptr, Some(llextra), _) = self else {
|
||||||
(llptr, llextra)
|
|
||||||
} else {
|
|
||||||
bug!("store_unsized called with a sized value")
|
bug!("store_unsized called with a sized value")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ Rust MIR: a lowered representation of Rust.
|
||||||
#![feature(exact_size_is_empty)]
|
#![feature(exact_size_is_empty)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(map_try_insert)]
|
#![feature(map_try_insert)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(slice_ptr_get)]
|
#![feature(slice_ptr_get)]
|
||||||
|
|
|
@ -145,9 +145,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||||
Ok([..]) => {}
|
Ok([..]) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let drop_trait = if let Some(did) = cx.tcx.lang_items().drop_trait() {
|
let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
|
||||||
did
|
|
||||||
} else {
|
|
||||||
// there is no way to define a type that needs non-const drop
|
// there is no way to define a type that needs non-const drop
|
||||||
// without having the lang item present.
|
// without having the lang item present.
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -449,11 +449,7 @@ pub trait Emitter {
|
||||||
span: &mut MultiSpan,
|
span: &mut MultiSpan,
|
||||||
children: &mut Vec<SubDiagnostic>,
|
children: &mut Vec<SubDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let source_map = if let Some(ref sm) = source_map {
|
let Some(source_map) = source_map else { return };
|
||||||
sm
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
debug!("fix_multispans_in_extern_macros: before: span={:?} children={:?}", span, children);
|
debug!("fix_multispans_in_extern_macros: before: span={:?} children={:?}", span, children);
|
||||||
self.fix_multispan_in_extern_macros(source_map, span);
|
self.fix_multispan_in_extern_macros(source_map, span);
|
||||||
for child in children.iter_mut() {
|
for child in children.iter_mut() {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(format_args_capture)]
|
#![feature(format_args_capture)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -447,9 +447,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
let mut undetermined_invocations = Vec::new();
|
let mut undetermined_invocations = Vec::new();
|
||||||
let (mut progress, mut force) = (false, !self.monotonic);
|
let (mut progress, mut force) = (false, !self.monotonic);
|
||||||
loop {
|
loop {
|
||||||
let (invoc, ext) = if let Some(invoc) = invocations.pop() {
|
let Some((invoc, ext)) = invocations.pop() else {
|
||||||
invoc
|
|
||||||
} else {
|
|
||||||
self.resolve_imports();
|
self.resolve_imports();
|
||||||
if undetermined_invocations.is_empty() {
|
if undetermined_invocations.is_empty() {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#![feature(format_args_capture)]
|
#![feature(format_args_capture)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(proc_macro_diagnostic)]
|
#![feature(proc_macro_diagnostic)]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
#![feature(proc_macro_span)]
|
#![feature(proc_macro_span)]
|
||||||
|
|
|
@ -116,10 +116,8 @@ pub(super) fn transcribe<'a>(
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Look at the last frame on the stack.
|
// 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.
|
// If it still has a TokenTree we have not looked at yet, use that tree.
|
||||||
tree
|
let Some(tree) = stack.last_mut().unwrap().next() else {
|
||||||
} else {
|
|
||||||
// This else-case never produces a value for `tree` (it `continue`s or `return`s).
|
// 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,
|
// Otherwise, if we have just reached the end of a sequence and we can keep repeating,
|
||||||
|
@ -190,9 +188,7 @@ pub(super) fn transcribe<'a>(
|
||||||
LockstepIterSize::Constraint(len, _) => {
|
LockstepIterSize::Constraint(len, _) => {
|
||||||
// We do this to avoid an extra clone above. We know that this is a
|
// We do this to avoid an extra clone above. We know that this is a
|
||||||
// sequence already.
|
// sequence already.
|
||||||
let (sp, seq) = if let mbe::TokenTree::Sequence(sp, seq) = seq {
|
let mbe::TokenTree::Sequence(sp, seq) = seq else {
|
||||||
(sp, seq)
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
|
|
@ -241,9 +241,7 @@ pub fn prepare_session_directory(
|
||||||
// have already tried before.
|
// have already tried before.
|
||||||
let source_directory = find_source_directory(&crate_dir, &source_directories_already_tried);
|
let source_directory = find_source_directory(&crate_dir, &source_directories_already_tried);
|
||||||
|
|
||||||
let source_directory = if let Some(dir) = source_directory {
|
let Some(source_directory) = source_directory else {
|
||||||
dir
|
|
||||||
} else {
|
|
||||||
// There's nowhere to copy from, we're done
|
// There's nowhere to copy from, we're done
|
||||||
debug!(
|
debug!(
|
||||||
"no source directory found. Continuing with empty session \
|
"no source directory found. Continuing with empty session \
|
||||||
|
@ -397,15 +395,14 @@ fn copy_files(sess: &Session, target_dir: &Path, source_dir: &Path) -> Result<bo
|
||||||
// We acquire a shared lock on the lock file of the directory, so that
|
// 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.
|
// nobody deletes it out from under us while we are reading from it.
|
||||||
let lock_file_path = lock_file_path(source_dir);
|
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,
|
&lock_file_path,
|
||||||
false, // don't wait,
|
false, // don't wait,
|
||||||
false, // don't create
|
false, // don't create
|
||||||
false,
|
false,
|
||||||
) {
|
) else {
|
||||||
// not exclusive
|
|
||||||
lock
|
|
||||||
} else {
|
|
||||||
// Could not acquire the lock, don't try to copy from here
|
// Could not acquire the lock, don't try to copy from here
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
|
|
|
@ -263,9 +263,7 @@ pub fn suggest_new_region_bound(
|
||||||
match fn_return.kind {
|
match fn_return.kind {
|
||||||
TyKind::OpaqueDef(item_id, _) => {
|
TyKind::OpaqueDef(item_id, _) => {
|
||||||
let item = tcx.hir().item(item_id);
|
let item = tcx.hir().item(item_id);
|
||||||
let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
|
let ItemKind::OpaqueTy(opaque) = &item.kind else {
|
||||||
opaque
|
|
||||||
} else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(extend_one)]
|
#![feature(extend_one)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
|
|
|
@ -472,9 +472,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
|
||||||
let len = BytePos::decode(decoder)?;
|
let len = BytePos::decode(decoder)?;
|
||||||
let hi = lo + len;
|
let hi = lo + len;
|
||||||
|
|
||||||
let sess = if let Some(sess) = decoder.sess {
|
let Some(sess) = decoder.sess else {
|
||||||
sess
|
|
||||||
} else {
|
|
||||||
bug!("Cannot decode Span without Session.")
|
bug!("Cannot decode Span without Session.")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#![feature(new_uninit)]
|
#![feature(new_uninit)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
|
|
|
@ -221,9 +221,7 @@ pub fn suggest_constraining_type_param(
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
|
let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
|
||||||
|
|
||||||
let param = if let Some(param) = param {
|
let Some(param) = param else {
|
||||||
param
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -755,17 +755,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the number of elements from the layout of the array field:
|
// 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, .. }, .. },
|
layout: Layout { fields: FieldsShape::Array { count, .. }, .. },
|
||||||
..
|
..
|
||||||
}) = self.layout_of(f0_ty)
|
}) = self.layout_of(f0_ty) else {
|
||||||
{
|
|
||||||
count
|
|
||||||
} else {
|
|
||||||
return Err(LayoutError::Unknown(ty));
|
return Err(LayoutError::Unknown(ty));
|
||||||
};
|
};
|
||||||
|
|
||||||
(*e_ty, *len, true)
|
(*e_ty, *count, true)
|
||||||
} else {
|
} else {
|
||||||
// First ADT field is not an array:
|
// First ADT field is not an array:
|
||||||
(f0_ty, def.non_enum_variant().fields.len() as _, false)
|
(f0_ty, def.non_enum_variant().fields.len() as _, false)
|
||||||
|
@ -787,9 +784,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
|
|
||||||
// Compute the ABI of the element type:
|
// Compute the ABI of the element type:
|
||||||
let e_ly = self.layout_of(e_ty)?;
|
let e_ly = self.layout_of(e_ty)?;
|
||||||
let e_abi = if let Abi::Scalar(scalar) = e_ly.abi {
|
let Abi::Scalar(e_abi) = e_ly.abi else {
|
||||||
scalar
|
|
||||||
} else {
|
|
||||||
// This error isn't caught in typeck, e.g., if
|
// This error isn't caught in typeck, e.g., if
|
||||||
// the element type of the vector is generic.
|
// the element type of the vector is generic.
|
||||||
tcx.sess.fatal(&format!(
|
tcx.sess.fatal(&format!(
|
||||||
|
|
|
@ -221,15 +221,13 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
|
||||||
let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local());
|
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 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(
|
find_capture_matching_projections(
|
||||||
typeck_results,
|
typeck_results,
|
||||||
var_hir_id,
|
var_hir_id,
|
||||||
closure_def_id,
|
closure_def_id,
|
||||||
&from_builder.projection,
|
&from_builder.projection,
|
||||||
) {
|
) else {
|
||||||
capture_details
|
|
||||||
} else {
|
|
||||||
if !enable_precise_capture(tcx, closure_span) {
|
if !enable_precise_capture(tcx, closure_span) {
|
||||||
bug!(
|
bug!(
|
||||||
"No associated capture found for {:?}[{:#?}] even though \
|
"No associated capture found for {:?}[{:#?}] even though \
|
||||||
|
|
|
@ -362,11 +362,7 @@ impl DropTree {
|
||||||
blocks: &IndexVec<DropIdx, Option<BasicBlock>>,
|
blocks: &IndexVec<DropIdx, Option<BasicBlock>>,
|
||||||
) {
|
) {
|
||||||
for (drop_idx, drop_data) in self.drops.iter_enumerated().rev() {
|
for (drop_idx, drop_data) in self.drops.iter_enumerated().rev() {
|
||||||
let block = if let Some(block) = blocks[drop_idx] {
|
let Some(block) = blocks[drop_idx] else { continue };
|
||||||
block
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
match drop_data.0.kind {
|
match drop_data.0.kind {
|
||||||
DropKind::Value => {
|
DropKind::Value => {
|
||||||
let terminator = TerminatorKind::Drop {
|
let terminator = TerminatorKind::Drop {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#![feature(exact_size_is_empty)]
|
#![feature(exact_size_is_empty)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
|
@ -290,9 +290,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> {
|
||||||
call: PeekCall,
|
call: PeekCall,
|
||||||
) {
|
) {
|
||||||
info!(?place, "peek_at");
|
info!(?place, "peek_at");
|
||||||
let local = if let Some(l) = place.as_local() {
|
let Some(local) = place.as_local() else {
|
||||||
l
|
|
||||||
} else {
|
|
||||||
tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
|
tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -312,9 +310,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
|
||||||
call: PeekCall,
|
call: PeekCall,
|
||||||
) {
|
) {
|
||||||
info!(?place, "peek_at");
|
info!(?place, "peek_at");
|
||||||
let local = if let Some(l) = place.as_local() {
|
let Some(local) = place.as_local() else {
|
||||||
l
|
|
||||||
} else {
|
|
||||||
tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
|
tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -673,9 +673,7 @@ impl Inliner<'tcx> {
|
||||||
assert!(args.next().is_none());
|
assert!(args.next().is_none());
|
||||||
|
|
||||||
let tuple = Place::from(tuple);
|
let tuple = Place::from(tuple);
|
||||||
let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_body, tcx).ty.kind() {
|
let ty::Tuple(tuple_tys) = tuple.ty(caller_body, tcx).ty.kind() else {
|
||||||
s
|
|
||||||
} else {
|
|
||||||
bug!("Closure arguments are not passed as a tuple");
|
bug!("Closure arguments are not passed as a tuple");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#![cfg_attr(bootstrap, feature(const_panic))]
|
#![cfg_attr(bootstrap, feature(const_panic))]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(map_try_insert)]
|
#![feature(map_try_insert)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(option_get_or_insert_default)]
|
#![feature(option_get_or_insert_default)]
|
||||||
|
|
|
@ -17,9 +17,7 @@ impl<'tcx> MirPass<'tcx> for LowerSliceLenCalls {
|
||||||
|
|
||||||
pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
let language_items = tcx.lang_items();
|
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() {
|
let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
|
||||||
slice_len_fn_item
|
|
||||||
} else {
|
|
||||||
// there is no language item to compare to :)
|
// there is no language item to compare to :)
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -208,7 +208,7 @@ fn normalize_array_len_call<'tcx>(
|
||||||
operand,
|
operand,
|
||||||
cast_ty,
|
cast_ty,
|
||||||
) => {
|
) => {
|
||||||
let local = if let Some(local) = place.as_local() { local } else { return };
|
let Some(local) = place.as_local() else { return };
|
||||||
match operand {
|
match operand {
|
||||||
Operand::Copy(place) | Operand::Move(place) => {
|
Operand::Copy(place) | Operand::Move(place) => {
|
||||||
let operand_local =
|
let operand_local =
|
||||||
|
@ -255,9 +255,7 @@ fn normalize_array_len_call<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rvalue::Len(place) => {
|
Rvalue::Len(place) => {
|
||||||
let local = if let Some(local) = place.local_or_deref_local() {
|
let Some(local) = place.local_or_deref_local() else {
|
||||||
local
|
|
||||||
} else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let Some(cast_statement_idx) = state.get(&local).copied() {
|
if let Some(cast_statement_idx) = state.get(&local).copied() {
|
||||||
|
|
|
@ -83,10 +83,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
|
||||||
let bb = BasicBlock::from_usize(bb);
|
let bb = BasicBlock::from_usize(bb);
|
||||||
trace!("processing block {:?}", bb);
|
trace!("processing block {:?}", bb);
|
||||||
|
|
||||||
let discriminant_ty =
|
let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) else {
|
||||||
if let Some(ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) {
|
|
||||||
ty
|
|
||||||
} else {
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
|
|
@ -458,9 +458,7 @@ fn mono_item_visibility(
|
||||||
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
||||||
|
|
||||||
// Upstream `DefId` instances get different handling than local ones.
|
// Upstream `DefId` instances get different handling than local ones.
|
||||||
let def_id = if let Some(def_id) = def_id.as_local() {
|
let Some(def_id) = def_id.as_local() else {
|
||||||
def_id
|
|
||||||
} else {
|
|
||||||
return if export_generics && is_generic {
|
return if export_generics && is_generic {
|
||||||
// If it is an upstream monomorphization and we export generics, we must make
|
// If it is an upstream monomorphization and we export generics, we must make
|
||||||
// it available to downstream crates.
|
// it available to downstream crates.
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(hash_raw_entry)]
|
#![feature(hash_raw_entry)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(thread_local_const_init)]
|
#![feature(thread_local_const_init)]
|
||||||
|
|
||||||
|
|
|
@ -644,9 +644,7 @@ pub fn print_query_stack<CTX: QueryContext>(
|
||||||
if Some(i) == num_frames {
|
if Some(i) == num_frames {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) {
|
let Some(query_info) = query_map.as_ref().and_then(|map| map.get(&query)) else {
|
||||||
info
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
let mut diag = Diagnostic::new(
|
let mut diag = Diagnostic::new(
|
||||||
|
|
|
@ -761,11 +761,9 @@ where
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = if let Some(key) =
|
let Some(key) =
|
||||||
<Q::Key as DepNodeParams<CTX::DepContext>>::recover(*tcx.dep_context(), &dep_node)
|
<Q::Key as DepNodeParams<CTX::DepContext>>::recover(*tcx.dep_context(), &dep_node)
|
||||||
{
|
else {
|
||||||
key
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1471,9 +1471,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
module: ModuleOrUniformRoot<'b>,
|
module: ModuleOrUniformRoot<'b>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
) -> Option<(Option<Suggestion>, Vec<String>)> {
|
) -> Option<(Option<Suggestion>, Vec<String>)> {
|
||||||
let mut crate_module = if let ModuleOrUniformRoot::Module(module) = module {
|
let ModuleOrUniformRoot::Module(mut crate_module) = module else {
|
||||||
module
|
|
||||||
} else {
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1057,9 +1057,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
let (name, reg) = Region::early(&self.tcx.hir(), &mut index, ¶m);
|
let (name, reg) = Region::early(&self.tcx.hir(), &mut index, ¶m);
|
||||||
let def_id = if let Region::EarlyBound(_, def_id, _) = reg {
|
let Region::EarlyBound(_, def_id, _) = reg else {
|
||||||
def_id
|
|
||||||
} else {
|
|
||||||
bug!();
|
bug!();
|
||||||
};
|
};
|
||||||
// We cannot predict what lifetimes are unused in opaque type.
|
// We cannot predict what lifetimes are unused in opaque type.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(format_args_capture)]
|
#![feature(format_args_capture)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#![feature(hash_drain_filter)]
|
#![feature(hash_drain_filter)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
|
|
|
@ -1038,13 +1038,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let hir = self.tcx.hir();
|
let hir = self.tcx.hir();
|
||||||
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
||||||
let node = hir.find(parent_node);
|
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),
|
kind: hir::ItemKind::Fn(sig, _, body_id),
|
||||||
..
|
..
|
||||||
})) = node
|
})) = node
|
||||||
{
|
else {
|
||||||
(sig, body_id)
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let body = hir.body(*body_id);
|
let body = hir.body(*body_id);
|
||||||
|
|
|
@ -647,9 +647,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty);
|
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 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 {
|
let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
|
||||||
(u, cu)
|
|
||||||
} else {
|
|
||||||
debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits");
|
debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -164,9 +164,7 @@ impl<'tcx> OnUnimplementedDirective {
|
||||||
) -> Result<Option<Self>, ErrorReported> {
|
) -> Result<Option<Self>, ErrorReported> {
|
||||||
let attrs = tcx.get_attrs(impl_def_id);
|
let attrs = tcx.get_attrs(impl_def_id);
|
||||||
|
|
||||||
let attr = if let Some(item) = tcx.sess.find_by_name(&attrs, sym::rustc_on_unimplemented) {
|
let Some(attr) = tcx.sess.find_by_name(&attrs, sym::rustc_on_unimplemented) else {
|
||||||
item
|
|
||||||
} else {
|
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -716,9 +716,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let data = if let ty::Dynamic(ref data, ..) = normalized_ty.kind() {
|
let ty::Dynamic(data, ..) = normalized_ty.kind() else {
|
||||||
data
|
|
||||||
} else {
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1916,9 +1916,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id);
|
debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id);
|
||||||
|
|
||||||
let self_ty = if let Some(ty) = opt_self_ty {
|
let Some(self_ty) = opt_self_ty else {
|
||||||
ty
|
|
||||||
} else {
|
|
||||||
let path_str = tcx.def_path_str(trait_def_id);
|
let path_str = tcx.def_path_str(trait_def_id);
|
||||||
|
|
||||||
let def_id = self.item_def_id();
|
let def_id = self.item_def_id();
|
||||||
|
|
|
@ -521,9 +521,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
|
|
||||||
let traits =
|
let traits =
|
||||||
(self.tcx.lang_items().unsize_trait(), self.tcx.lang_items().coerce_unsized_trait());
|
(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 {
|
let (Some(unsize_did), Some(coerce_unsized_did)) = traits else {
|
||||||
(u, cu)
|
|
||||||
} else {
|
|
||||||
debug!("missing Unsize or CoerceUnsized traits");
|
debug!("missing Unsize or CoerceUnsized traits");
|
||||||
return Err(TypeError::Mismatch);
|
return Err(TypeError::Mismatch);
|
||||||
};
|
};
|
||||||
|
|
|
@ -743,9 +743,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let src = if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
|
let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) else {
|
||||||
src
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -502,9 +502,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// FIXME: Instead of exiting early when encountering bound vars in
|
// FIXME: Instead of exiting early when encountering bound vars in
|
||||||
// the function signature, consider keeping the binder here and
|
// the function signature, consider keeping the binder here and
|
||||||
// propagating it downwards.
|
// propagating it downwards.
|
||||||
let fn_sig = if let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() {
|
let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() else {
|
||||||
fn_sig
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -718,10 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ti: TopInfo<'tcx>,
|
ti: TopInfo<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
// Resolve the path and check the definition for errors.
|
// 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)
|
let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
|
||||||
{
|
|
||||||
variant_ty
|
|
||||||
} else {
|
|
||||||
let err = self.tcx.ty_error();
|
let err = self.tcx.ty_error();
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let ti = TopInfo { parent_pat: Some(pat), ..ti };
|
let ti = TopInfo { parent_pat: Some(pat), ..ti };
|
||||||
|
|
|
@ -411,9 +411,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
debug!("convert_place_op_to_mutable: method={:?}", method);
|
debug!("convert_place_op_to_mutable: method={:?}", method);
|
||||||
self.write_method_call(expr.hir_id, method);
|
self.write_method_call(expr.hir_id, method);
|
||||||
|
|
||||||
let region = if let ty::Ref(r, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() {
|
let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else {
|
||||||
r
|
|
||||||
} else {
|
|
||||||
span_bug!(expr.span, "input to mutable place op is not a mut ref?");
|
span_bug!(expr.span, "input to mutable place op is not a mut ref?");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1000,11 +1000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
|
let Some(root_var_min_capture_list) = min_captures.and_then(|m| m.get(&var_hir_id)) else {
|
||||||
min_captures.and_then(|m| m.get(&var_hir_id))
|
|
||||||
{
|
|
||||||
root_var_min_capture_list
|
|
||||||
} else {
|
|
||||||
// The upvar is mentioned within the closure but no path starting from it is
|
// The upvar is mentioned within the closure but no path starting from it is
|
||||||
// used.
|
// used.
|
||||||
|
|
||||||
|
@ -1077,9 +1073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
closure_clause: hir::CaptureBy,
|
closure_clause: hir::CaptureBy,
|
||||||
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
|
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
|
||||||
) -> (Vec<MigrationDiagnosticInfo>, String) {
|
) -> (Vec<MigrationDiagnosticInfo>, String) {
|
||||||
let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
|
let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) else {
|
||||||
upvars
|
|
||||||
} else {
|
|
||||||
return (Vec::new(), format!(""));
|
return (Vec::new(), format!(""));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1684,9 +1678,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
||||||
diag_expr_id: hir::HirId,
|
diag_expr_id: hir::HirId,
|
||||||
) {
|
) {
|
||||||
let tcx = self.fcx.tcx;
|
let tcx = self.fcx.tcx;
|
||||||
let upvar_id = if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
|
let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else {
|
||||||
upvar_id
|
|
||||||
} else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(is_sorted)]
|
#![feature(is_sorted)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue