Don't call closures immediately, use try{}
blocks
This commit is contained in:
parent
bddbf38af2
commit
360e978437
@ -47,42 +47,22 @@ pub(super) fn compare_impl_method<'tcx>(
|
||||
|
||||
let impl_m_span = tcx.def_span(impl_m.def_id);
|
||||
|
||||
if let Err(_) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) = compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m, false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) =
|
||||
compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) = compare_synthetic_generics(tcx, impl_m, trait_m) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) = compare_asyncness(tcx, impl_m, impl_m_span, trait_m, trait_item_span) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) = compare_method_predicate_entailment(
|
||||
tcx,
|
||||
impl_m,
|
||||
impl_m_span,
|
||||
trait_m,
|
||||
impl_trait_ref,
|
||||
CheckImpliedWfMode::Check,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
let _: Result<_, ErrorGuaranteed> = try {
|
||||
compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)?;
|
||||
compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false)?;
|
||||
compare_generic_param_kinds(tcx, impl_m, trait_m, false)?;
|
||||
compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?;
|
||||
compare_synthetic_generics(tcx, impl_m, trait_m)?;
|
||||
compare_asyncness(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?;
|
||||
compare_method_predicate_entailment(
|
||||
tcx,
|
||||
impl_m,
|
||||
impl_m_span,
|
||||
trait_m,
|
||||
impl_trait_ref,
|
||||
CheckImpliedWfMode::Check,
|
||||
)?;
|
||||
};
|
||||
}
|
||||
|
||||
/// This function is best explained by example. Consider a trait:
|
||||
@ -1493,7 +1473,7 @@ fn compare_synthetic_generics<'tcx>(
|
||||
// explicit generics
|
||||
(true, false) => {
|
||||
err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
|
||||
(|| {
|
||||
let _: Option<_> = try {
|
||||
// try taking the name from the trait impl
|
||||
// FIXME: this is obviously suboptimal since the name can already be used
|
||||
// as another generic argument
|
||||
@ -1526,14 +1506,13 @@ fn compare_synthetic_generics<'tcx>(
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
Some(())
|
||||
})();
|
||||
};
|
||||
}
|
||||
// The case where the trait method uses `impl Trait`, but the impl method uses
|
||||
// explicit generics.
|
||||
(false, true) => {
|
||||
err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
|
||||
(|| {
|
||||
let _: Option<_> = try {
|
||||
let impl_m = impl_m.def_id.as_local()?;
|
||||
let impl_m = tcx.hir().expect_impl_item(impl_m);
|
||||
let input_tys = match impl_m.kind {
|
||||
@ -1573,8 +1552,7 @@ fn compare_synthetic_generics<'tcx>(
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
Some(())
|
||||
})();
|
||||
};
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -1799,7 +1777,7 @@ pub(super) fn compare_impl_ty<'tcx>(
|
||||
) {
|
||||
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
|
||||
|
||||
let _: Result<(), ErrorGuaranteed> = (|| {
|
||||
let _: Result<(), ErrorGuaranteed> = try {
|
||||
compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?;
|
||||
|
||||
compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
|
||||
@ -1807,8 +1785,8 @@ pub(super) fn compare_impl_ty<'tcx>(
|
||||
let sp = tcx.def_span(impl_ty.def_id);
|
||||
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;
|
||||
|
||||
check_type_bounds(tcx, trait_ty, impl_ty, impl_ty_span, impl_trait_ref)
|
||||
})();
|
||||
check_type_bounds(tcx, trait_ty, impl_ty, impl_ty_span, impl_trait_ref)?;
|
||||
};
|
||||
}
|
||||
|
||||
/// The equivalent of [compare_method_predicate_entailment], but for associated types
|
||||
|
@ -251,7 +251,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
VarValue::Empty(a_universe) => {
|
||||
let b_data = var_values.value_mut(b_vid);
|
||||
|
||||
let changed = (|| match *b_data {
|
||||
let changed = match *b_data {
|
||||
VarValue::Empty(b_universe) => {
|
||||
// Empty regions are ordered according to the universe
|
||||
// they are associated with.
|
||||
@ -280,20 +280,20 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
};
|
||||
|
||||
if lub == cur_region {
|
||||
return false;
|
||||
false
|
||||
} else {
|
||||
debug!(
|
||||
"Expanding value of {:?} from {:?} to {:?}",
|
||||
b_vid, cur_region, lub
|
||||
);
|
||||
|
||||
*b_data = VarValue::Value(lub);
|
||||
true
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Expanding value of {:?} from {:?} to {:?}",
|
||||
b_vid, cur_region, lub
|
||||
);
|
||||
|
||||
*b_data = VarValue::Value(lub);
|
||||
true
|
||||
}
|
||||
|
||||
VarValue::ErrorValue => false,
|
||||
})();
|
||||
};
|
||||
|
||||
if changed {
|
||||
changes.push(b_vid);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#![feature(internal_output_capture)]
|
||||
#![feature(thread_spawn_unchecked)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(try_blocks)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
|
@ -559,7 +559,7 @@ fn write_out_deps(
|
||||
}
|
||||
let deps_filename = outputs.path(OutputType::DepInfo);
|
||||
|
||||
let result = (|| -> io::Result<()> {
|
||||
let result: io::Result<()> = try {
|
||||
// Build a list of files used to compile the output and
|
||||
// write Makefile-compatible dependency rules
|
||||
let mut files: Vec<String> = sess
|
||||
@ -646,9 +646,7 @@ fn write_out_deps(
|
||||
writeln!(file)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})();
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
|
@ -159,18 +159,20 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
|
||||
}
|
||||
chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)),
|
||||
chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)),
|
||||
chalk_ir::TyKind::Tuple(len, substs) => Some((|| {
|
||||
write!(fmt, "(")?;
|
||||
for (idx, substitution) in substs.interned().iter().enumerate() {
|
||||
if idx == *len && *len != 1 {
|
||||
// Don't add a trailing comma if the tuple has more than one element
|
||||
write!(fmt, "{:?}", substitution)?;
|
||||
} else {
|
||||
write!(fmt, "{:?},", substitution)?;
|
||||
chalk_ir::TyKind::Tuple(len, substs) => Some(
|
||||
try {
|
||||
write!(fmt, "(")?;
|
||||
for (idx, substitution) in substs.interned().iter().enumerate() {
|
||||
if idx == *len && *len != 1 {
|
||||
// Don't add a trailing comma if the tuple has more than one element
|
||||
write!(fmt, "{:?}", substitution)?;
|
||||
} else {
|
||||
write!(fmt, "{:?},", substitution)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
write!(fmt, ")")
|
||||
})()),
|
||||
write!(fmt, ")")?;
|
||||
},
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -86,10 +86,10 @@ pub(super) fn build_custom_mir<'tcx>(
|
||||
block_map: FxHashMap::default(),
|
||||
};
|
||||
|
||||
let res = (|| {
|
||||
let res: PResult<_> = try {
|
||||
pctxt.parse_args(¶ms)?;
|
||||
pctxt.parse_body(expr)
|
||||
})();
|
||||
pctxt.parse_body(expr)?;
|
||||
};
|
||||
if let Err(err) = res {
|
||||
tcx.sess.diagnostic().span_fatal(
|
||||
err.span,
|
||||
|
@ -113,7 +113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
//
|
||||
// it is usually better to focus on `the_value` rather
|
||||
// than the entirety of block(s) surrounding it.
|
||||
let adjusted_span = (|| {
|
||||
let adjusted_span =
|
||||
if let ExprKind::Block { block } = expr.kind
|
||||
&& let Some(tail_ex) = this.thir[block].expr
|
||||
{
|
||||
@ -135,10 +135,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
tail_result_is_ignored: true,
|
||||
span: expr.span,
|
||||
});
|
||||
return Some(expr.span);
|
||||
}
|
||||
None
|
||||
})();
|
||||
Some(expr.span)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let temp =
|
||||
unpack!(block = this.as_temp(block, statement_scope, expr, Mutability::Not));
|
||||
|
@ -141,27 +141,23 @@ impl IntRange {
|
||||
) -> Option<IntRange> {
|
||||
let ty = value.ty();
|
||||
if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) {
|
||||
let val = (|| {
|
||||
match value {
|
||||
mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) => {
|
||||
// For this specific pattern we can skip a lot of effort and go
|
||||
// straight to the result, after doing a bit of checking. (We
|
||||
// could remove this branch and just fall through, which
|
||||
// is more general but much slower.)
|
||||
return scalar.to_bits_or_ptr_internal(target_size).unwrap().left();
|
||||
let val =
|
||||
if let mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) = value {
|
||||
// For this specific pattern we can skip a lot of effort and go
|
||||
// straight to the result, after doing a bit of checking. (We
|
||||
// could remove this branch and just fall through, which
|
||||
// is more general but much slower.)
|
||||
scalar.to_bits_or_ptr_internal(target_size).unwrap().left()?
|
||||
} else {
|
||||
if let mir::ConstantKind::Ty(c) = value
|
||||
&& let ty::ConstKind::Value(_) = c.kind()
|
||||
{
|
||||
bug!("encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val");
|
||||
}
|
||||
mir::ConstantKind::Ty(c) => match c.kind() {
|
||||
ty::ConstKind::Value(_) => bug!(
|
||||
"encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val"
|
||||
),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// This is a more general form of the previous case.
|
||||
value.try_eval_bits(tcx, param_env, ty)
|
||||
})()?;
|
||||
// This is a more general form of the previous case.
|
||||
value.try_eval_bits(tcx, param_env, ty)?
|
||||
};
|
||||
let val = val ^ bias;
|
||||
Some(IntRange { range: val..=val, bias })
|
||||
} else {
|
||||
|
@ -208,14 +208,12 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
_ => {
|
||||
// This `for` loop was once a call to `all()`, but this lower-level
|
||||
// form was a perf win. See #64545 for details.
|
||||
(|| {
|
||||
for &infer_var in &pending_obligation.stalled_on {
|
||||
if self.selcx.infcx.ty_or_const_infer_var_changed(infer_var) {
|
||||
return true;
|
||||
}
|
||||
for &infer_var in &pending_obligation.stalled_on {
|
||||
if self.selcx.infcx.ty_or_const_infer_var_changed(infer_var) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
})()
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
// wait to fold the substs.
|
||||
|
||||
// Wrap this in a closure so we don't accidentally return from the outer function
|
||||
let res = (|| match *ty.kind() {
|
||||
let res = match *ty.kind() {
|
||||
// This is really important. While we *can* handle this, this has
|
||||
// severe performance implications for large opaque types with
|
||||
// late-bound regions. See `issue-88862` benchmark.
|
||||
@ -210,7 +210,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
{
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty.try_super_fold_with(self),
|
||||
Reveal::UserFacing => ty.try_super_fold_with(self)?,
|
||||
|
||||
Reveal::All => {
|
||||
let substs = substs.try_fold_with(self)?;
|
||||
@ -230,7 +230,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
if concrete_ty == ty {
|
||||
bug!(
|
||||
"infinite recursion generic_ty: {:#?}, substs: {:#?}, \
|
||||
concrete_ty: {:#?}, ty: {:#?}",
|
||||
concrete_ty: {:#?}, ty: {:#?}",
|
||||
generic_ty,
|
||||
substs,
|
||||
concrete_ty,
|
||||
@ -239,7 +239,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
}
|
||||
let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty));
|
||||
self.anon_depth -= 1;
|
||||
folded_ty
|
||||
folded_ty?
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -287,9 +287,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
// `tcx.normalize_projection_ty` may normalize to a type that still has
|
||||
// unevaluated consts, so keep normalizing here if that's the case.
|
||||
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
|
||||
Ok(res.try_super_fold_with(self)?)
|
||||
res.try_super_fold_with(self)?
|
||||
} else {
|
||||
Ok(res)
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,14 +344,14 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
// `tcx.normalize_projection_ty` may normalize to a type that still has
|
||||
// unevaluated consts, so keep normalizing here if that's the case.
|
||||
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
|
||||
Ok(res.try_super_fold_with(self)?)
|
||||
res.try_super_fold_with(self)?
|
||||
} else {
|
||||
Ok(res)
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
_ => ty.try_super_fold_with(self),
|
||||
})()?;
|
||||
_ => ty.try_super_fold_with(self)?,
|
||||
};
|
||||
|
||||
self.cache.insert(ty, res);
|
||||
Ok(res)
|
||||
|
Loading…
x
Reference in New Issue
Block a user