1
Fork 0

Stop doing expensive work in opt_suggest_box_span eagerly

This commit is contained in:
Michael Goulet 2024-03-24 12:23:36 -04:00
parent 10a7aa14fe
commit 2fe936f17d
11 changed files with 217 additions and 191 deletions

View file

@ -1262,24 +1262,6 @@ pub enum SuggestAccessingField<'a> {
},
}
#[derive(Subdiagnostic)]
pub enum SuggestBoxingForReturnImplTrait {
#[multipart_suggestion(infer_sbfrit_change_return_type, applicability = "maybe-incorrect")]
ChangeReturnType {
#[suggestion_part(code = "Box<dyn")]
start_sp: Span,
#[suggestion_part(code = ">")]
end_sp: Span,
},
#[multipart_suggestion(infer_sbfrit_box_return_expr, applicability = "maybe-incorrect")]
BoxReturnExpr {
#[suggestion_part(code = "Box::new(")]
starts: Vec<Span>,
#[suggestion_part(code = ")")]
ends: Vec<Span>,
},
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(infer_stp_wrap_one, applicability = "maybe-incorrect")]
pub struct SuggestTuplePatternOne {

View file

@ -784,7 +784,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
prior_arm_ty,
source,
ref prior_non_diverging_arms,
opt_suggest_box_span,
scrut_span,
..
}) => match source {
@ -853,17 +852,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) {
err.subdiagnostic(self.dcx(), subdiag);
}
if let Some(ret_sp) = opt_suggest_box_span {
// Get return type span and point to it.
self.suggest_boxing_for_return_impl_trait(
err,
ret_sp,
prior_non_diverging_arms
.iter()
.chain(std::iter::once(&arm_span))
.copied(),
);
}
}
},
ObligationCauseCode::IfExpression(box IfExpressionCause {
@ -872,7 +860,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
then_ty,
else_ty,
outer_span,
opt_suggest_box_span,
..
}) => {
let then_span = self.find_block_span_from_hir_id(then_id);
let else_span = self.find_block_span_from_hir_id(else_id);
@ -890,30 +878,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) {
err.subdiagnostic(self.dcx(), subdiag);
}
// don't suggest wrapping either blocks in `if .. {} else {}`
let is_empty_arm = |id| {
let hir::Node::Block(blk) = self.tcx.hir_node(id) else {
return false;
};
if blk.expr.is_some() || !blk.stmts.is_empty() {
return false;
}
let Some((_, hir::Node::Expr(expr))) = self.tcx.hir().parent_iter(id).nth(1)
else {
return false;
};
matches!(expr.kind, hir::ExprKind::If(..))
};
if let Some(ret_sp) = opt_suggest_box_span
&& !is_empty_arm(then_id)
&& !is_empty_arm(else_id)
{
self.suggest_boxing_for_return_impl_trait(
err,
ret_sp,
[then_span, else_span].into_iter(),
);
}
}
ObligationCauseCode::LetElse => {
err.help("try adding a diverging expression, such as `return` or `panic!(..)`");

View file

@ -19,9 +19,8 @@ use rustc_span::{sym, BytePos, Span};
use crate::errors::{
ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
FunctionPointerSuggestion, SuggestAccessingField, SuggestBoxingForReturnImplTrait,
SuggestRemoveSemiOrReturnBinding, SuggestTuplePatternMany, SuggestTuplePatternOne,
TypeErrorAdditionalDiags,
FunctionPointerSuggestion, SuggestAccessingField, SuggestRemoveSemiOrReturnBinding,
SuggestTuplePatternMany, SuggestTuplePatternOne, TypeErrorAdditionalDiags,
};
use super::TypeErrCtxt;
@ -80,28 +79,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}
pub(super) fn suggest_boxing_for_return_impl_trait(
&self,
err: &mut Diag<'_>,
return_sp: Span,
arm_spans: impl Iterator<Item = Span>,
) {
let sugg = SuggestBoxingForReturnImplTrait::ChangeReturnType {
start_sp: return_sp.with_hi(return_sp.lo() + BytePos(4)),
end_sp: return_sp.shrink_to_hi(),
};
err.subdiagnostic(self.dcx(), sugg);
let mut starts = Vec::new();
let mut ends = Vec::new();
for span in arm_spans {
starts.push(span.shrink_to_lo());
ends.push(span.shrink_to_hi());
}
let sugg = SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends };
err.subdiagnostic(self.dcx(), sugg);
}
pub(super) fn suggest_tuple_pattern(
&self,
cause: &ObligationCause<'tcx>,

View file

@ -229,6 +229,15 @@ impl<'tcx> InferCtxtInner<'tcx> {
.expect("region constraints already solved")
.with_log(&mut self.undo_log)
}
// Iterates through the opaque type definitions without taking them; this holds the
// `InferCtxtInner` lock, so make sure to not do anything with `InferCtxt` side-effects
// while looping through this.
pub fn iter_opaque_types(
&self,
) -> impl Iterator<Item = (ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>)> + '_ {
self.opaque_type_storage.opaque_types.iter().map(|(&k, v)| (k, v.hidden_type))
}
}
pub struct InferCtxt<'tcx> {