Skip to content

Commit 6c4f40d

Browse files
Make closures inherit their parent's "safety context"
1 parent 8d1e3d3 commit 6c4f40d

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+30-2
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,30 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
213213
self.requires_unsafe(expr.span, CastOfPointerToInt);
214214
}
215215
}
216+
ExprKind::Closure {
217+
closure_id,
218+
substs: _,
219+
upvars: _,
220+
movability: _,
221+
fake_reads: _,
222+
} => {
223+
let closure_id = closure_id.expect_local();
224+
let closure_def = if let Some((did, const_param_id)) =
225+
ty::WithOptConstParam::try_lookup(closure_id, self.tcx)
226+
{
227+
ty::WithOptConstParam { did, const_param_did: Some(const_param_id) }
228+
} else {
229+
ty::WithOptConstParam::unknown(closure_id)
230+
};
231+
let (closure_thir, expr) = self.tcx.thir_body(closure_def);
232+
let closure_thir = &closure_thir.borrow();
233+
let hir_context = self.tcx.hir().local_def_id_to_hir_id(closure_id);
234+
let mut closure_visitor =
235+
UnsafetyVisitor { thir: closure_thir, hir_context, ..*self };
236+
closure_visitor.visit_expr(&closure_thir[expr]);
237+
// Unsafe blocks can be used in closures, make sure to take it into account
238+
self.safety_context = closure_visitor.safety_context;
239+
}
216240
_ => {}
217241
}
218242

@@ -335,14 +359,18 @@ impl UnsafeOpKind {
335359
}
336360
}
337361

338-
// FIXME: checking unsafety for closures should be handled by their parent body,
339-
// as they inherit their "safety context" from their declaration site.
340362
pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) {
341363
// THIR unsafeck is gated under `-Z thir-unsafeck`
342364
if !tcx.sess.opts.debugging_opts.thir_unsafeck {
343365
return;
344366
}
345367

368+
// Closures are handled by their parent function
369+
if tcx.is_closure(def.did.to_def_id()) {
370+
tcx.ensure().thir_check_unsafety(tcx.hir().local_def_id_to_hir_id(def.did).owner);
371+
return;
372+
}
373+
346374
let (thir, expr) = tcx.thir_body(def);
347375
let thir = &thir.borrow();
348376
// If `thir` is empty, a type error occured, skip this body.

0 commit comments

Comments
 (0)