Rollup merge of #108705 - clubby789:refutable-let-closure-borrow, r=cjgillot
Prevent ICE with broken borrow in closure r? `@Nilstrieb` Fixes #108683 This solution isn't ideal, I'm hoping to find a way to continue compilation without ICEing.
This commit is contained in:
commit
40d933a19a
5 changed files with 154 additions and 13 deletions
|
@ -42,7 +42,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
|
|||
// Ensure unsafeck and abstract const building is ran before we steal the THIR.
|
||||
tcx.ensure_with_value().thir_check_unsafety(def);
|
||||
tcx.ensure_with_value().thir_abstract_const(def);
|
||||
tcx.ensure_with_value().check_match(def);
|
||||
if let Err(e) = tcx.check_match(def) {
|
||||
return construct_error(tcx, def, e);
|
||||
}
|
||||
|
||||
let body = match tcx.thir_body(def) {
|
||||
Err(error_reported) => construct_error(tcx, def, error_reported),
|
||||
|
|
|
@ -26,8 +26,8 @@ use rustc_session::Session;
|
|||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::Span;
|
||||
|
||||
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
let Ok((thir, expr)) = tcx.thir_body(def_id) else { return };
|
||||
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
let (thir, expr) = tcx.thir_body(def_id)?;
|
||||
let thir = thir.borrow();
|
||||
let pattern_arena = TypedArena::default();
|
||||
let mut visitor = MatchVisitor {
|
||||
|
@ -37,13 +37,16 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
lint_level: tcx.hir().local_def_id_to_hir_id(def_id),
|
||||
let_source: LetSource::None,
|
||||
pattern_arena: &pattern_arena,
|
||||
error: Ok(()),
|
||||
};
|
||||
visitor.visit_expr(&thir[expr]);
|
||||
|
||||
for param in thir.params.iter() {
|
||||
if let Some(box ref pattern) = param.pat {
|
||||
visitor.check_irrefutable(pattern, "function argument", None);
|
||||
}
|
||||
}
|
||||
visitor.error
|
||||
}
|
||||
|
||||
fn create_e0004(
|
||||
|
@ -77,6 +80,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
|
|||
lint_level: HirId,
|
||||
let_source: LetSource,
|
||||
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
|
||||
error: Result<(), ErrorGuaranteed>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
|
||||
|
@ -276,9 +280,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
let [pat_field] = &subpatterns[..] else { bug!() };
|
||||
self.check_irrefutable(&pat_field.pattern, "`for` loop binding", None);
|
||||
} else {
|
||||
non_exhaustive_match(
|
||||
self.error = Err(non_exhaustive_match(
|
||||
&cx, self.thir, scrut_ty, scrut.span, witnesses, arms, expr_span,
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +410,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||
fn check_irrefutable(&mut self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||
let mut cx = self.new_cx(self.lint_level, false);
|
||||
|
||||
let pattern = self.lower_pattern(&mut cx, pat);
|
||||
|
@ -475,7 +479,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
AdtDefinedHere { adt_def_span, ty, variants }
|
||||
};
|
||||
|
||||
self.tcx.sess.emit_err(PatternNotCovered {
|
||||
self.error = Err(self.tcx.sess.emit_err(PatternNotCovered {
|
||||
span: pat.span,
|
||||
origin,
|
||||
uncovered: Uncovered::new(pat.span, &cx, witnesses),
|
||||
|
@ -486,7 +490,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
let_suggestion,
|
||||
misc_suggestion,
|
||||
adt_defined_here,
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,7 +632,7 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
|
||||
arms: &[ArmId],
|
||||
expr_span: Span,
|
||||
) {
|
||||
) -> ErrorGuaranteed {
|
||||
let is_empty_match = arms.is_empty();
|
||||
let non_empty_enum = match scrut_ty.kind() {
|
||||
ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
|
||||
|
@ -640,13 +644,12 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
let pattern;
|
||||
let patterns_len;
|
||||
if is_empty_match && !non_empty_enum {
|
||||
cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty {
|
||||
return cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty {
|
||||
cx,
|
||||
expr_span,
|
||||
span: sp,
|
||||
ty: scrut_ty,
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// FIXME: migration of this diagnostic will require list support
|
||||
let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
|
||||
|
@ -797,7 +800,7 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
} else {
|
||||
err.help(msg);
|
||||
}
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
pub(crate) fn joined_uncovered_patterns<'p, 'tcx>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue