1
Fork 0

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:
Matthias Krüger 2023-05-11 07:05:26 +02:00 committed by GitHub
commit 40d933a19a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 154 additions and 13 deletions

View file

@ -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),

View file

@ -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>(